我一直在学习编程,我选择了 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 等价物是 C++ 中的 char**, char*&。在 C# 中没有区别。
所以您看不到速度上的任何差异,因为实际执行的代码是相同的。
这也不完全是它停止的地方,你实际上从来没有对数组做任何事情。您调用的方法会在运行时消失,就像它在 C 或 C++ 编译器中一样,它将被优化器内联。由于您不使用数组参数,因此您也不会获得任何代码。
当您使用指针来实际寻址内存时,指针对于加快程序速度很有用。您可以索引数组并确保您永远不会为数组边界检查付费。在许多情况下,您也不会在正常使用情况下为它付费,如果抖动优化器知道索引始终是安全的,它会非常聪明地删除检查。这是指针的不安全用法,您可以轻松地在不属于数组的内存部分中乱写,并以这种方式破坏 GC 堆。用于对象引用或 ref 参数的指针永远不会不安全。
了解这些内容的唯一真实方法是查看生成的机器代码。调试 + Windows + 反汇编窗口。重要的是允许代码仍然被优化,即使你调试它或者你看不到优化。一定要运行 Release 构建并使用 Tools + Options、Debugging、General,取消勾选“Suppress JIT optimization on module load”选项。需要对机器代码有一定的了解才能理解您所看到的内容。
关于C# 指针与 C++ 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23557148/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
>>a=5=>5>>b=a=>5>>b=4=>4>>a=>5如何将“b”设置为实际的“a”,以便在示例中,变量a也将变为4。谢谢。 最佳答案 classRefdefinitializeval@val=valendattr_accessor:valdefto_s@val.to_sendenda=Ref.new(4)b=aputsa#=>4putsb#=>4a.val=5putsa#=>5putsb#=>5当您执行b=a时,b指向与a相同的对象(它们具有相同的object_id).当你执行a=some_other_thing时,a将指向
出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t