C++数组与C#ptr速度混淆

Dan*_*cik 6 c# c++ arrays performance

我正在为C#重写一个高性能的C++应用程序.C#应用程序明显慢于C++原始版本.分析告诉我C#app花费大部分时间来访问数组元素.因此我创建了一个简单的数组访问基准.我得到的结果与其他进行类似比较的结果完全不同.

C++代码:

#include <limits>
#include <stdio.h>
#include <chrono>
#include <iostream>

using namespace std;
using namespace std::chrono;

int main(void)
{
    high_resolution_clock::time_point t1 = high_resolution_clock::now();

    int xRepLen = 100 * 1000;
    int xRepCount = 1000;

    unsigned short * xArray = new unsigned short[xRepLen];
    for (int xIdx = 0; xIdx < xRepLen; xIdx++)
        xArray[xIdx] = xIdx % USHRT_MAX;

    int * xResults = new int[xRepLen];

    for (int xRepIdx = 0; xRepIdx < xRepCount; xRepIdx++)
    {

        // in each repetition, find the first value, that surpasses xArray[xIdx] + 25 - i.e. we will perform 25 searches
        for (int xIdx = 0; xIdx < xRepLen; xIdx++)
        {
            unsigned short xValToBreach = (xArray[xIdx] + 25) % USHRT_MAX;
            xResults[xIdx] = 0;

            for (int xIdx2 = xIdx + 1; xIdx2 < xRepLen; xIdx2++)
            if (xArray[xIdx2] >= xValToBreach)
            {
                xResults[xIdx] = xIdx2; break;
            }

            if (xResults[xIdx] == 0)
                xResults[xIdx] = INT_MAX;
        }
    }

    high_resolution_clock::time_point t2 = high_resolution_clock::now();
    auto duration = duration_cast<milliseconds>(t2 - t1).count();
    cout << "Elasped miliseconds " << duration;
    getchar();
}
Run Code Online (Sandbox Code Playgroud)

C#代码:

using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace arrayBenchmarkCs
{
    class Program
    {
        public static void benchCs()
        {
            unsafe
            {
                int xRepLen = 100 * 1000;
                int xRepCount = 1000;

                ushort[] xArr = new ushort[xRepLen];
                for (int xIdx = 0; xIdx < xRepLen; xIdx++)
                    xArr[xIdx] = (ushort)(xIdx % 0xffff);

                int[] xResults = new int[xRepLen];

                Stopwatch xSw = new Stopwatch(); xSw.Start();
                fixed (ushort * xArrayStart = & xArr [0])
                {
                    for (int xRepIdx = 0; xRepIdx < xRepCount; xRepIdx++)
                    {

                        // in each repetition, go find the first value, that surpasses xArray[xIdx] + 25 - i.e. we will perform 25 searches
                        ushort * xArrayEnd = xArrayStart + xRepLen;
                        for (ushort* xPtr = xArrayStart; xPtr != xArrayEnd; xPtr++)
                        {
                            ushort xValToBreach = (ushort)((*xPtr + 25) % 0xffff);
                            int xResult = -1;
                            for (ushort * xPtr2 = xPtr + 1; xPtr2 != xArrayEnd; xPtr2++)
                                if ( *xPtr2  >= xValToBreach)
                                {
                                    xResult = (int)(xPtr2 - xArrayStart);
                                    break;
                                }

                            if (xResult == -1)
                                xResult = int.MaxValue;

                            // save result
                            xResults[xPtr - xArrayStart] = xResult;
                        }
                    }
                }   // fixed

                xSw.Stop();

                Console.WriteLine("Elapsed miliseconds: " + (xSw.ElapsedMilliseconds.ToString("0"));
            }
        }

        static void Main(string[] args)
        {
            benchCs();
            Console.ReadKey();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的工作计算机(i7-3770)上,C++版本比C#版本快约2倍.在我的家用计算机(i7-5820K)上,C++比C#版本快1.5倍.两者都在Release中测量.我希望通过在C#中使用指针来避免数组边界检查,并且两种语言的性能都是相同的.

所以我的问题如下:

  • 其他人发现C#与C++的速度相同?
  • 如果不是通过指针,我怎样才能将C#性能提升到C++级别?
  • 什么可能是不同计算机上不同加速的驱动程序?

丹尼尔非常感谢任何提示

Ric*_*ons 0

您无法以 C++ 的速度进行这种核心数字运算。使用指针算术和不安全的代码可以让你达到目标(如果删除不安全和固定的部分,速度几乎会减半)。C# 不会编译为本机代码,并且它运行的代码充满了额外的检查和内容。

如果您愿意unsafe,那么实际上没有什么可以阻止您将 C++ 性能关键的内容编码到混合模式程序集中,并从 C# 粘合代码中调用它。