C#指针与C ++指针 [英] C# pointers vs. C++ pointers

查看:79
本文介绍了C#指针与C ++指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在学习编程,因此我选择了C ++和C#编程作为第一语言.更具体地说,我有一本古老的C书,有人很善良,可以借给我,我正在用它来学习C#.我使用Visual Studio Express并用C ++和C#编写.我感兴趣的一个领域是进行直接内存管理的能力.我正在尝试学习使用它来优化我的代码.但是,我正在努力做到正确,并且实际上看到了任何实际的性能改进.例如,下面是C#中的以下代码:

I have been learning to program and I chose C++ and C# programming as first languages. More specifically, I have an old C book someone was kind enough to let me borrow and I'm using it to learn C#. I use Visual Studio Express and write in C++ and C#. One area that interests me is the ability to do direct memory management. I am trying to learn to use this to optimize my code. However, I am struggling to do it properly and actually see any real performance improvement. For example, here is the following code in 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和使用指针之间的区别,除非那可能会花费一些时间和练习.

No matter which of three methods I call, I am getting the same execution speed. I'm also still trying to wrap my head around the difference between using ref and using a pointer, except that's probably something that will take time and practice.

但是,我不了解的是,我能够在C ++中产生非常显着的性能差异.当我尝试在C ++中近似相同的代码时,这就是我想到的:

What I don't understand, however, is that I am able to produce a very significant performance difference in C++. Here is what I came up with when I attempted to approximate the same code in 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#代码不能从我对引用或指针的使用中受益?我一直在网上阅读东西,除了卡住了.

Can anyone tell me why my C# code isn't benefitting from my use of references or pointers? I've been reading stuff online and whatnot, except I'm stuck.

推荐答案

C#已经生成了指针,而无需您显式声明它们.实际上,每个引用类型引用(例如您的 numbers 变量)都是运行时的指针.使用 ref out 关键字传递的每个参数实际上都是运行时的指针.数组参数的确切C等价字符是char **,char *&在C ++中. C#没有区别.

C# already generates pointers without you explicitly declaring them. Every reference type reference, like your numbers variable, is in fact a pointer at runtime. Every argument you pass with the ref or out keywords are in fact pointers at runtime. The exact C equivalent of your array argument is char**, char*& in C++. There's no difference in C#.

因此您不会看到速度上的任何差异,因为实际执行的代码是相同的.

So you don't see any difference in speed because the code that actually executes is the same.

那也不是它停止的确切位置,您实际上从未对数组做任何事情.您调用的方法会在运行时消失,就像在C或C ++编译器中一样,优化器将对其进行内联.而且由于不使用array参数,因此也不会得到任何代码.

That isn't exactly where it stops either, you never actually do anything with the array. The method you call disappears at runtime, much like it does in a C or C++ compiler, it will be inlined by the optimizer. And since you don't use the array argument, you don't get any code for it either.

当您使用指针实际寻址内存时,它们对于加速程序很有用.您可以为数组建立索引,并确保您永远不会为数组边界检查付费.在许多情况下,您也不会为通常的使用付费,如果抖动优化器知道索引始终是安全的,则它对于删除检查相当明智.指针的使用是不安全,您可以轻松地将其写入不属于该数组的内存部分,并以此破坏GC堆.用于对象引用或 ref 参数的指针永远不会不安全.

Pointers become useful to speed programs up when you use them to actually address memory. You can index the array and be sure that you'll never pay for the array bounds check. You won't pay for it in normal usage in many cases either, the jitter optimizer is fairly smart about removing the checks if it knows that the indexing is always safe. That's unsafe usage of a pointer, you can readily scribble into parts of memory that don't belong to the array and corrupt the GC heap that way. The pointers used for an object reference or a ref argument are never unsafe.

查看其中任何一种的唯一真实方法是查看生成的机器代码.调试+ Windows +反汇编窗口.重要的是,即使您调试了代码或看不到优化,仍要对代码进行优化.确保运行发布"版本,并使用工具+选项",调试",常规",取消选中在模块加载时禁止JIT优化"选项.需要对机器代码有所了解才能理解您所看到的内容.

The only real way to see any of this is to look at the generated machine code. Debug + Windows + Disassembly window. It is important that allow code to still be optimized even though you debug it or you can't see the optimizations. Be sure to run the Release build and use Tools + Options, Debugging, General, untick the "Suppress JIT optimization on module load" option. Some familiarity with machine code is required to make sense of what you see.

这篇关于C#指针与C ++指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆