微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 如何在避免间接调用的同时编写通用代码?

有没有办法在C#中调用写通用程序和算法,同时避免动态解决方案的开销?

考虑一个简单的例子:

static void QuickSort<T>(T[] arr,int left,int right,Comparison<T> compare)
{
    do
    {
        int i = left;
        int j = right;
        var x = arr[i + ((j - i) >> 1)];
        do
        {
            while (i < arr.Length && compare(x,arr[i]) > 0) i++;
            while (j >= 0 && compare(x,arr[j]) < 0) j--;
            if (i > j) { break; }
            if (i < j)
            {
                var temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
            i++;
            j--;
        } while (i <= j);
        if (j - left <= right - i)
        {
            if (left < j) QuickSort(arr,left,j,compare);
            left = i;
        }
        else
        {
            if (i < right) QuickSort(arr,i,right,compare);
            right = j;
        }
    } while (left < right);
}

您可以称之为:

QuickSort(buffer,buffer.Length - 1,(a,b) => a.Compareto(b))

虽然看起来很有效,但这个看起来很好看的例子为每次比较执行间接(即虚拟)调用.

显然,处理器无法优化间接呼叫,因此它们的性能很差.在我的计算机上,这意味着性能下降了25%,从大约3,600项/ ms减少到2,700项/ ms.

有没有办法在编写通用代码时避免这种间接调用
无论我对委托,Dynamicmethod等做多少杂耍,似乎总是在库代码用户代码之间进行间接调用,这显然会对性能产生非常不利的影响.

解决方法

如果比较项目,答案是否定的:你不能把一个>在x和arr [j]之间,并期望编译器弄清楚你的意思是它应用它的内置>对类型为T的对象的运算符

但是,您的解决方案可能会稍微优化一下,因为您要为间接付费两次.由于您已宣布您的T为IC Comparable< T>已经,你可以删除比较器参数,并调用x.Compareto(arr [j])而不通过lambda.这将减少第二个间接的开销.当然,它不会让您自定义比较项目的方式,但这将是支付cpu周期灵活性的例行情况.

原文地址:https://www.jb51.cc/csharp/244137.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐