最近好不容易抽出点时间对《华容道》的程序做了番调整,发现程序的性能瓶颈居然在Array.Sort上面!经过调整后,程序运行时间缩短了1秒(河北石家庄李智广编写的华容道全能版V1.1第19关)!
微软的System.Array类提供了一个静态方法Sort,可以很方便的对一维数据进行排序。对于比较懒的我,一向直接使用Array.Sort完成对数组的排序。今天才发现原来Array.Sort存在严重的效率问题。先来看一段使用Array.Sort进行自定义排序的例子。
using System;
using System.Collections;

public class DataElement
{
public int value;
public DataElement() {}
public DataElement(int value) { this.value = value; }
}

public class DataElementComparer : IComparer
{
public int Compare(object x, object y)
{
return ((DataElement)x).value.CompareTo(((DataElement)y).value);
}
}

public class Client
{
public static void Main()
{
int[] a = {5,8,3,6,9};
DataElement[] d = new DataElement[5];

for(int i=0; i<5; i++)
d[i] = new DataElement(a[i]);

Array.Sort(d, new DataElementComparer());

for(int i = 0; i<5; i++)
Console.Write(d[i].value + ", ");
}
}
注意,在上面的例子中,为了实现自定义类(DataElement)的排序,我设计了一个DataElementComparer类,实现了System.Collections.IComparer接口。这样,在应用Array.Sort方法时,同时提供要排序的数组以及DataElementComparer的一个实例,便可以进行排序了。
但需要注意的是,在.net 2003中没有泛型的支持,所以IComparer接口在定义时,Compare方法接收的参数是object类型。因此,在进行比较时需要对值类型数据进行反复Box和UnBox操作,而对于引用类型则反复进行UpCast和DownCast操作,严重影响了效率!
在C# 2.0规范中提供了泛型机制,我想IComparer接口应当重新进行了定义,Array.Sort的效率应当比现在要强很多。我后来将《华容道》中应用Array.Sort的地方改为了使用“快速排序法”代码,效率一下子上去了。解题时间从原来的7.4秒缩短到了6.4秒,可是不小的进步呀!快速排序法代码如下(具体算法可以参考《数据结构》中的相关章节):
using System;

public class DataElement
{
public int value;
public DataElement() {}
public DataElement(int value) { this.value = value; }
}

public class QuickSortArray
{
public DataElement[] list;

public void quickSort()
{
recQuickSort(0, list.Length - 1);
}

private void recQuickSort(int first, int last)
{
int pivotLocation;

if(first < last)
{
pivotLocation = partition(first, last);
recQuickSort(first, pivotLocation - 1);
recQuickSort(pivotLocation + 1, last);
}
}

private int partition(int first, int last)
{
DataElement pivot;
int index, smallIndex;

swap(first, (first + last) / 2);
pivot = list[first];
smallIndex = first;

for(index = first + 1; index <= last; index++)
if(list[index].value < pivot.value)
{
smallIndex++;
swap(smallIndex, index);
}

swap(first, smallIndex);
return smallIndex;
}

private void swap(int first, int second)
{
DataElement temp;

temp = list[first];
list[first] = list[second];
list[second] = temp;
}
}
public class Client
{
public static void Main()
{
int[] a = {42, 43, 0, 1, 3, 20, 31, 32, 40, 41, 21, 23};

QuickSortArray qs = new QuickSortArray();
qs.list = new DataElement[12];

for(int i=0; i<12; i++)
qs.list[i] = new DataElement(a[i]);

qs.quickSort();

for(int i=0; i<12; i++)
Console.WriteLine(qs.list[i].value + ", ");
}
}
微软的System.Array类提供了一个静态方法Sort,可以很方便的对一维数据进行排序。对于比较懒的我,一向直接使用Array.Sort完成对数组的排序。今天才发现原来Array.Sort存在严重的效率问题。先来看一段使用Array.Sort进行自定义排序的例子。


































注意,在上面的例子中,为了实现自定义类(DataElement)的排序,我设计了一个DataElementComparer类,实现了System.Collections.IComparer接口。这样,在应用Array.Sort方法时,同时提供要排序的数组以及DataElementComparer的一个实例,便可以进行排序了。
但需要注意的是,在.net 2003中没有泛型的支持,所以IComparer接口在定义时,Compare方法接收的参数是object类型。因此,在进行比较时需要对值类型数据进行反复Box和UnBox操作,而对于引用类型则反复进行UpCast和DownCast操作,严重影响了效率!
在C# 2.0规范中提供了泛型机制,我想IComparer接口应当重新进行了定义,Array.Sort的效率应当比现在要强很多。我后来将《华容道》中应用Array.Sort的地方改为了使用“快速排序法”代码,效率一下子上去了。解题时间从原来的7.4秒缩短到了6.4秒,可是不小的进步呀!快速排序法代码如下(具体算法可以参考《数据结构》中的相关章节):














































































【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架