繁体   English   中英

C#指针与C ++指针

[英]C# pointers vs. C++ pointers

我一直在学习编程,我选择C ++和C#编程作为第一语言。 更具体地说,我有一本旧的C书,有人让我借用,我正在用它来学习C#。 我使用Visual Studio Express并使用C ++和C#编写。 我感兴趣的一个领域是直接内存管理的能力。 我正在努力学习如何使用它来优化我的代码。 但是,我正在努力做到这一点,实际上看到任何真正的性能提升。 例如,以下是C#中的以下代码:

unsafe static void Main(string[] args)
{
    int size = 300000;
    char[] numbers = new char[size];

    for (int i = 0; i < size; i++)
    {
        numbers[i] = '7';
    }

    DateTime start = DateTime.Now;

    fixed (char* c = &numbers[0])
    {
        for (int i = 0; i < 10000000; i++)
        {
            int number = myFunction(c, 100000);
        }
    }

    /*char[] c = numbers;  // commented out C# non-pointer version same 
          speed as C# pointer version
    {
        for (int i = 0; i < 10000000; i++)
        {
            int number = myFunction(c, 100000);
        }
    }*/

    TimeSpan timeSpan = DateTime.Now - start;
    Console.WriteLine(timeSpan.TotalMilliseconds.ToString());
    Console.ReadLine();
}

static int myFunction(ref char[] numbers, int size)
{
    return size * 100;
}

static int myFunction(char[] numbers, int size)
{
    return size * 100;
}

unsafe static int myFunction(char* numbers, int size)
{
    return size * 100;
}

无论我调用哪三种方法,我都获得相同的执行速度。 我还在尝试围绕使用ref和使用指针之间的区别,除了这可能需要时间和练习。

然而,我不明白的是,我能够在C ++中产生非常显着的性能差异。 当我尝试在C ++中使用相同的代码时,我想到了以下内容:

/*int myFunction(std::string* numbers, int size)  // C++ pointer version commented 
     out is much faster than C++ non-pointer version
{
    return size * 100;
}*/

int myFunction(std::string numbers, int size) // value version
{
    return size * 100;
}

int _tmain(int argc, _TCHAR* argv[])
{
int size = 100000;
std::string numbers = "";
for (int i = 0; i < size; i++)
{
    numbers += "777";
}

clock_t start = clock();

for (int i = 0; i < 10000; i++)
{
    int number = myFunction(numbers, 100000);
}

clock_t timeSpan = clock() - start;

std::cout << timeSpan;
char c;
std::cin >> c;

return 0;
}

任何人都可以告诉我为什么我的C#代码不会受益于我对引用或指针的使用? 我一直在网上读东西,除了我被卡住了。

C#已经生成了指针而没有你明确地声明它们。 每个引用类型引用(如数字变量)实际上都是运行时的指针。 使用refout关键字传递的每个参数实际上都是运行时的指针。 数组参数的确切C等价物是char **,char *&C ++。 C#没有区别。

所以你没有看到速度上的任何差异,因为实际执行的代码是相同的。

这不是它停止的地方,你从来没有对数组做任何事情。 您调用的方法在运行时消失,就像在C或C ++编译器中一样,它将由优化器内联 由于您不使用数组参数,因此您也没有获得任何代码。

当您使用它们来实际处理内存时,指针对于加速程序非常有用。 您可以索引数组,并确保您永远不会支付数组边界检查。 在许多情况下,您不会在正常使用情况下为此付费,如果抖动优化器知道索引始终是安全的,那么删除检查是相当明智的。 这是指针的不安全使用,你可以随便乱写到不属于该数组的内存部分并以这种方式破坏GC堆。 用于对象引用或ref参数的指针永远不会安全。

查看其中任何一个的唯一真正方法是查看生成的机器代码。 Debug + Windows + Disassembly窗口。 重要的是,即使您调试代码仍然需要优化,或者您无法看到优化​​。 确保运行Release版本并使用Tools + Options,Debugging,General,取消选中“在模块加载时抑制JIT优化”选项。 需要熟悉机器代码才能理解您所看到的内容。

问题是你没有测量你认为你在测量的东西。 我可以阅读你的代码,并立即看到为什么你会得到这个结果或结果,这不仅仅是因为指针或指针。 还有许多其他因素在起作用,或者可能起作用。 各种评论反映了这一点。

对于它的价值,一个C ++调用比另一个慢得多的主要原因是因为慢速复制std :: string而快速复制没有。 C#示例没有类似它们之间的差异顺序。

我的建议是,作为一个聪明但早期的程序员,你首先关注的是成为一个更好的程序员。 在您知道自己要实现的目标之前,不要担心“优化”。

当您准备好真正理解这个问题时,您将不得不研究生成的代码。 在C#的情况下,它是MSIL,以及它在特定平台上的JIT。 在C ++的情况下,英特尔为任何处理器操作代码。 直到你知道MSIL和JIT和操作码是什么,理解为什么你得到你所做的结果将很难解释。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM