c#指针vs. 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#已经生成了指针,而无需显式声明它们。每个引用类型引用,比如numbers变量,实际上在运行时都是一个指针。使用ref或out关键字传递的每个参数实际上在运行时都是指针。与你的数组参数完全等价的C语言是char**, char*&在c++中。在c#中没有区别。
所以你看不到任何速度上的差异,因为实际执行的代码是一样的。
这也不是它停止的地方,你从来没有对数组做过任何事情。您调用的方法在运行时消失,就像在C或c++编译器中一样,它将被优化器内联。因为你不使用array参数,你也不会得到任何代码。
当您使用指针来实际寻址内存时,
指针对于加快程序非常有用。您可以索引数组,并确保您永远不会为数组边界检查付费。在许多情况下,在正常使用中您也不会为此付费,如果抖动优化器知道索引总是安全的,它就会相当聪明地删除检查。这是不安全的使用指针,您可以很容易地将不属于数组的内存部分涂入,并以这种方式破坏GC堆。用于对象引用或ref参数的指针从来不是不安全的。
查看这些的唯一方法是查看生成的机器码。调试+ Windows +反汇编窗口。重要的是,即使您调试了代码,或者无法看到优化结果,也要允许代码仍然得到优化。确保运行Release build并使用Tools + Options, Debugging, General,取消"在模块加载上抑制JIT优化"选项。要理解所看到的内容,需要对机器码有一定的了解。
问题是你没有衡量你认为你在衡量的东西。我可以读一下你的代码,立刻明白为什么你会得到这个结果或那个结果,这不仅仅是因为指针或非指针。还有很多其他因素在起作用,或者可能在起作用。各种注释反映了这一点。
无论如何,一个c++调用比另一个慢得多的主要原因是慢的调用复制了std::string,而快的调用没有。c#示例之间没有任何类似的顺序差异。
我的建议是,作为一个聪明但处于早期阶段的程序员,你首先要专注于成为一个更好的程序员。在你知道你想要达到什么目标之前,不要担心"优化"。
当你准备好真正理解这个问题时,你将不得不研究生成的代码。在c#的情况下,这是MSIL,以及它在特定平台上的任何东西。在c++的情况下,这是英特尔的操作码为任何处理器。在您了解什么是MSIL、JIT和操作码之前,很难解释为什么会得到这样的结果。
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 调整大小后指向元素值的指针unordered_map有效?
- 正在将指针转换为范围
- 使用指向成员的指针将成员函数作为参数传递
- 将OpenCV C++重写为EmguCV C#-如何使用指针
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错