c# - 在 C# 中拆分数组的最快(可移植)方法

标签 c# optimization

我正在编写一个完全托管的 Mercurial 库(用于完全托管的 Mercurial Server for Windows,即将推出),我遇到的最严重的性能问题之一是,奇怪的是,将数组拆分为零件。

想法如下:有一个字节数组,大小从几百字节到一兆字节不等,我需要用它做的就是将它分成几个部分,在我的具体情况下,\n 个字符。

现在 dotTrace 向我显示的是我的 "optimized" version Split(代码 是正确的,我开始使用的 here's the naive 版本)在 2,300 次调用中占用了 11 秒(dotTrace 本身引入了明显的性能影响,但是一切都符合规模)。

这是数字:

  • 不安全 版本:11 297 ms for 2 312 calls
  • 托管(“原始”)版本:20 001 ms for 2 312 calls

所以这里是:在 C# 中拆分数组的最快方式(最好是可移植的,意味着同时支持 x86 和 x64)。

最佳答案

我认为问题在于,您在循环中执行了很多复杂的操作。这段代码去掉了循环内除了单次加法和比较之外的所有操作。其他复杂的事情只有在检测到拆分或在数组末尾时才会发生。

此外,很难说出您使用哪种数据运行测试,因此这只是猜测。

public static unsafe Segment[] Split2(byte[] _src, byte value)
{
    var _ln = _src.Length;

    if (_ln == 0) return new Segment[] { };

    fixed (byte* src = _src)
    {
        var segments = new LinkedList<Segment>(); // Segment[c];

        byte* last = src;
        byte* end = src + _ln - 1;
        byte lastValue = *end;
        *end = value; // value-termination

        var cur = src;
        while (true)
        {
            if (*cur == value)
            {
                int begin = (int) (last - src);
                int length = (int) (cur - last + 1);
                segments.AddLast(new Segment(_src, begin, length));

                last = cur + 1;

                if (cur == end)
                {
                    if (lastValue != value)
                    {
                        *end = lastValue;
                    }
                    break;
                }
            }
            cur++;
        }

        return segments.ToArray();
    }
}

编辑:修改代码,使其返回正确的结果。

关于c# - 在 C# 中拆分数组的最快(可移植)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12133163/

相关文章:

algorithm - 除了使用循环展开之外,还有其他优化向量矩阵乘法的方法吗?

c - 在 clang 中启用优化时是否定义了内置宏?

c++ - gcc 会根据条件优化我的循环吗?

c# - Xamarin.Forms Shell 在视觉层次结构之外导航

c# - .NET 的 GUID 结构

c# - 使用 'with' 关键字复制记录结构时重新初始化仅获取属性

c# - 在 C# 中使用 SSH.NET SFTP 下载目录

c# - Windows 窗体屏幕保护程序预览窗口句柄

c++ - 只通过一次if语句

java - 登录 Java 的最快方法是什么?