当前位置: 首页 > 编程语言 > C#

无法重现:C ++ Vector性能优于C#List性能分享

时间:2023-04-11 02:15:40 C#

C#学习教程:不可重现:C++VectorPerformanceIsBetterThanC#List++有“真正的数组”,C#/Java语言没有相同或相似之处。我被卖了。您可以在http://channel9.msdn.com/Events/Build/2014/2-661观看完整的演讲这是他描述的幻灯片的快照。http://sofzh.miximages.com/c%23/DQaiF.png但我想知道我会有多不同。所以我写了一个非常天真的测试程序,它从一个文件中创建一个大的字符串向量,每行的长度从5个字符到50个字符不等。链接到文件:www(dot)dropbox.com/s/evxn9iq3fu8qwss/result.txt我按顺序访??问它们。我已经用C#和C++完成了这个练习。注意:我做了一些修改以按照建议删除循环中的重复项。感谢您帮助我了解Real数组。在C#中,我使用了List和ArrayList,因为不推荐使用ArrayList而使用了List。以下是我的戴尔笔记本电脑与Corei7处理器的结果:countC#(List)C#(ArrayList)C++100024ms21ms7ms10000214ms213ms64ms1000002sec123ms5ms6sec2C#代码:usingSystem;使用System.Collections.Generic;使用系统诊断;使用System.Linq;使用系统文本;使用System.Threading.Tasks;使用系统集合;命名空间CSConsole{类程序{staticvoidMain(string[]args){intcount;boolsuccess=int.TryParse(args[0],outcount);varwatch=new秒表();System.IO.StreamReaderisrc=newSystem.IO.StreamReader("result.txt");ArrayList列表=newArrayList();while(!isrc.EndOfStream){list.Add(isrc.ReadLine());}双k=0;观看。开始();for(inti=0;i(time_now()-start).count();}int_tmain(intargc,_TCHAR*argv[]){intcount=_wtoi(argv[1]);向量vs;fstreamfs("result.txt",fstream::in);if(!fs)return-1;char*buffer=newchar[1024];while(!fs.eof()){fs.getline(buffer,1024);vs.push_back(string(buffer,fs.gcount()));}doublek=0;autoconststart=time_now();for(inti=0;i=0;i--){vs.Add(newValueHolder(i,0,0));//用标签i构造valueholder,blahsof0}varwatch=newStopwatch();观看。开始();for(inti=0;iC++代码:classValueHolder{public:inttag;intblah;intotherBlah;ValueHolder(intt,intb,into):tag(t),blah(b),otherBlah(o){}};constValueHolder&findHolderWithTag(vector&buffer,inttag){//找到带有标签i的holderfor(constauto&holder:buffer){if(holder.tag==tag)返回持有者;}staticValueHolderempty{0,0,0};返回空;}int_tmain(intargc,_TCHAR*argv[]){constintMAX=99999;整数计数=1000;//_wtoi(argv[1]);矢量与;for(inti=MAX;i>=0;i--){对比emplace_back(i,0,0);//用标签i构建valueholder,0}autoconststart=time_now();for(inti=0;i我们已经从最初的问题中知道,在C#中创建一堆重复列表比在C++中快得多,但是我如何搜索列表?两个程序都只是进行愚蠢的线性列表扫描,只是为了展示这一点。在我的电脑上,C++版本运行72ms,C#版本需要620ms。为什么速度提高了?因为“真正的数组”。所有C++ValueHolders在一个std::vector中彼此相邻。当循环想要读取下一个循环时,这意味着它很可能已经在CPU缓存中。C#ValueHolders位于各种随机内存位置,列表仅包含指向它们的指针。当循环想要读取下一个循环时,几乎肯定不在CPU缓存中,所以我们必须去读取它。内存访问很慢,所以C#版本需要几乎10倍的时间。如果将C#ValueHolder从class更改为struct,那么C#List可以将它们全部放入内存,时间下降到161毫秒。当您插入列表时,Buuut现在必须制作一个副本。C#问题在于,在许多情况下,您不能或不想使用结构,而在C++中,您可以更好地控制这些事情。PS:Java没有结构,所以你根本不能那样做。你被10倍缓存卡住了std::string是可变容器,而C#的字符串是不可变的。这意味着可以共享两个C#字符串的数据:复制C#字符串会复制指针(也称为引用),并执行互锁生命周期管理工作。复制std::string复制内容(写入C++std::string复制是不合法的)。要创建一组更相似的C++代码,请将std::shared_ptr存储在vector中。填充重复向量时,请确保仅复制智能指针。现在你有(智能)指向不可变数据的指针,就像C#一样。请注意,这可能会提高C++中的复制性能,但会使大多数其他操作变慢(如果你想编辑一个std::string你现在必须复制整个东西,然后修改副本,并读取额外的指针取消引用)。结构immutable_string{immutable_string()=默认值;不可变字符串(常量&)=默认值;不可变字符串(&&)=默认值;immutable_string&operator=(const&)=default;immutable_string&operator=(&&)=default;immutable_string(std::strings):data(std::make_shared(std::move(s))){}std::stringconst&get()const{if(data)return*data;返回*empty_string();}std::stringget()&&{if(!data)返回{};if(data->use_count()==1)returnstd::move(const_cast(*data));返回*数据;}templatevoidemplace(Args&&...args){data=std::make_shared(std::forward(args)...);}templatevoidmodify(F&&f){std::stringtmp=std::move(*this).get();std::forward(f)(tmp);安置(标准::移动(tmp));私有:std::shared_ptr数据;staticstd::shared_ptrempty_string(){staticautonothing=std::make_shared();什么都不返回;}};这给了我们牛。要编辑,调用immutable_strings;s.modify([&](std::string&s){immutable_strings;s.modify([&](std::string&s){codegoeshere});以上是C#学习教程:不可重现:C++Vector的性能优于C#List的性能所有分享的内容,如果对大家有用,需要进一步了解C#LearningTutorial,希望大家多加关注——本文来自网络合集,不代表立场,如涉及侵权,请点击右边联系管理员删除,如需转载请注明出处: