看到一个吵架贴,也来参与一把

43 views
Skip to first unread message

qiaojie

unread,
Jun 22, 2010, 2:49:53 AM6/22/10
to pon...@googlegroups.com
原文在此:
看到有人跳出来炮轰.net的性能问题,虽然说这位老兄列举的论据没一条靠谱,但是在这里我们先不管他的逻辑谬误,我想澄清一下对 .net性能的一些误解。
首先,.net是基于虚拟机的,所以无法做到像c/c++那样面向贴近机器模型,主要的限制在于内存模型无法做到c/c++那样的灵活性,因此这决定了 .net不适合作为面向底层的系统级编程平台。但是这种灵活性的限制跟性能并不是等价的,不能简单的归咎为性能问题。
其次,撇开内存模型,在执行上 .net的JIT在性能上是很有竞争力的,关于这点可以从JIT的原理以及JIT生成的汇编代码中窥见一二,大部分情况下在性能上是可以接近c代码的,而把动态语言远远的甩在后面。由于各个编程平台的实现的细节完全不同,我们不可能通过几个简单的benchmark就能说明性能差异,所以各种语言的性能之争总是喋喋不休,但却没有一个定论。记得去年有人比较了python的字符串排序比C++的还要快,原因只能因为python的运行期库实现了一个更高效的排序算法,而这显然不能说明python的性能比C++高。在此,我也不打算给出一个定论。
最后,说说 .net的应用。我在游戏行业做过多年,.net在游戏中的应用其实还是比较广泛的。客户端方面,比较著名的当属XNA,还有这两年很火的Unity(用的mono)。阻碍.net用在客户端的障碍主要还是一个部署问题,要玩家安装游戏之前先安装一个几十上百兆的runtime,确实不是那么容易令人接受。除了客户端,.net也很适合用来开发游戏编辑器之类的工具类软件,有了c++/cli的帮助,.net跟c++的集成性是非常好的,可以很容易的把一个c++开发的引擎包装成供c#调用的模块。我们也有把.net用在开发mmo服务器以及棋牌类服务器的经验,应该说我们在服务器领域利用.net来开发还是相当成功的,有效的降低了开发成本,缩短了开发时间,也从来没有被 .net特有的性能问题困扰过(要说有的话也是其他语言都会面临的问题)。

laogao

unread,
Jun 22, 2010, 2:59:44 AM6/22/10
to pon...@googlegroups.com
就我从Gmail看到的效果而言,.net这个名称的url解析器不友好的特点暴露无遗。就事论事。

2010/6/22 qiaojie <qia...@gmail.com>:

--
regards,
laogao
http://laogao.me | http://twitter.com/laogao

Jeffrey Zhao

unread,
Jun 22, 2010, 3:03:23 AM6/22/10
to pon...@googlegroups.com
且C#,F#这些名字对于SEO不友好。

翁翊成

unread,
Jun 22, 2010, 3:09:47 AM6/22/10
to pon...@googlegroups.com
也可以写做dot Net嘛

在 2010年6月22日 下午2:59,laogao <gaoyu...@gmail.com>写道:
就我从Gmail看到的效果而言,.net这个名称的url解析器不友好的特点暴露无遗。就事论事。

 
338.gif

Jeffrey Zhao

unread,
Jun 22, 2010, 3:15:14 AM6/22/10
to pon...@googlegroups.com
话说微软其实很傻,或者说很懒,把.NET 3.5搞得100多兆,.NET 4.0终于想清楚了,把Client Profile的体积缩小到29M,Full也只有35M了。
 
 
 

Milo Yip

unread,
Jun 22, 2010, 3:15:58 AM6/22/10
to pon...@googlegroups.com
我認為C++編譯器在情能上的優勢還是有不少。例如可以關掉exception、全局優化。不肯定現在的.Net能否做到,或是理論上是否能做到。另外的就是硬件方面的了,手寫intrinsic(SIMD)、alignment等等。
而在執行環境上,據我所知,.Net在interop上也會做成不少開銷。
雖然我沒寫過XNA和Unity,但朋友對它們的效能評價並不高。

--
Milo Yip

Twitter @miloyip
http://www.cnblogs.com/miloyip/
http://miloyip.seezone.net/

Changsheng Jiang

unread,
Jun 22, 2010, 3:26:13 AM6/22/10
to pon...@googlegroups.com
这里全局優化是指跨目标文件的優化么? 链结器也能优化修改代码? 还是?

                                                     Changsheng Jiang


2010/6/22 Milo Yip <mil...@gmail.com>

Milo Yip

unread,
Jun 22, 2010, 3:34:29 AM6/22/10
to pon...@googlegroups.com

qiaojie

unread,
Jun 22, 2010, 3:38:15 AM6/22/10
to pon...@googlegroups.com
主要的劣势有两个方面吧
1、操作数组和对象时有一些隐含的validation,如BoundsCheck. null pointer check
2、不支持SIMD指令(mono号称可以支持,不确定)
异常不会是问题,没人会在性能关键的代码里抛异常。
不过这些在我看来不是问题,如果真要写一个性能很敏感的关键代码,完全可以用C/C++来实现,再包装一下给.net使用。
 

 
2010/6/22 Milo Yip <mil...@gmail.com>

Milo Yip

unread,
Jun 22, 2010, 4:49:20 AM6/22/10
to pon...@googlegroups.com
C#也特別提供了unchecked和unsafe。
不知道.Net implementation如何實現exception呢。
如果是code approach,那麼不throw也會有些許overhead。

Yingjie XU

unread,
Jun 22, 2010, 5:17:09 AM6/22/10
to pon...@googlegroups.com
说个题外话,我一直觉得叫.Net是因为在linux下面就被隐藏了

2010/6/22 Jeffrey Zhao <je...@live.com>



--
Yingjie XU
Département d'informatique
École Normale Supérieure
45 rue d'Ulm
F-75230 Paris Cedex 05

"If you received this communication by mistake,
please don't forward it to anyone else (it may contain
confidential or privileged information), please erase
all copies of it, including all attachments, and please
let the sender know it went to the wrong person.
Thanks."

周迪

unread,
Jun 22, 2010, 8:58:30 AM6/22/10
to pon...@googlegroups.com
那与java相比呢?我感觉java强大的类库和平台通用性会更好一些。可能性能上两者都差不多。
--
周迪

qiaojie

unread,
Jun 22, 2010, 10:14:16 AM6/22/10
to pon...@googlegroups.com
我对java没有兴趣,这个让老赵去比较吧。

2010/6/22 周迪 <zhoud...@gmail.com>

Jeffrey Zhao

unread,
Jun 22, 2010, 10:41:44 AM6/22/10
to pon...@googlegroups.com
两个平台都太博大精深了,比较不过来,我最多比较Java和C#语言之类的特定角度的内容。总之Java平台挺好,除了Java语言外我都很喜欢很有兴趣。

Jeffrey Zhao
Blog: http://blog.zhaojie.me/
Twitter: @jeffz_cn

From: qiaojie
Sent: Tuesday, June 22, 2010 10:14 PM
Subject: Re: [TL] 看到一个吵架贴,也来参与一把

Milo Yip

unread,
Jun 22, 2010, 10:51:29 AM6/22/10
to pon...@googlegroups.com
剛 port 了一個99行C的全局渲染器到C#,結果讓我很驚喜... 先再檢查一下才寫blog :)

--

est

unread,
Jun 23, 2010, 11:54:36 PM6/23/10
to pon...@googlegroups.com
哈哈。。。.NET才出来那些日子很奇怪。连金山词霸都叫 金山词霸.NET,虽然跟.NET没有一点关系。

2010/6/22 Yingjie XU <jdkl...@gmail.com>:

qiaojie

unread,
Jun 23, 2010, 11:56:40 PM6/23/10
to pon...@googlegroups.com
顺便还可以port到java, python, javascrpt, lua上,这样比较就全面了。


 
2010/6/22 Milo Yip <mil...@gmail.com>

Milo Yip

unread,
Jun 24, 2010, 12:22:03 AM6/24/10
to pon...@googlegroups.com
昨晚又因為沒有做profiling,有網友發現random generator佔了一半時間,就急忙去換一個custom made的。

寫這類博文真難啊... 不過也想試試Java,沒有value type (C# struct),用GC應該一定沒命,哈哈。

Jeffrey Zhao

unread,
Jun 24, 2010, 1:00:07 AM6/24/10
to pon...@googlegroups.com
看到那个分析,说C#程序的Level 1 Cache Miss很高,浮点数计算消耗也很大,这个是很奇怪的。有机会我也想仔细比较一下两者的汇编,只可惜我现在没有合适的Windows环境袅……
 

Jeffrey Zhao
Blog: http://blog.zhaojie.me/

qiaojie

unread,
Jun 24, 2010, 2:28:35 AM6/24/10
to pon...@googlegroups.com
L1 Cache miss高是因为这段C#代码里有很多vec, ray之类的临时变量,C#编译器会老老实实的生成这些临时变量,导致运行栈内存占用超过L1大小,而C++编译器的一个很重要的优化是把临时变量通过内联等手段合并优化掉,所以运行栈占用会小很多。不过其实.net不是没有办法优化的,用unsafe代码是可以做到的,只是用C#改起来比较麻烦,所以我偷了个懒,直接把C++代码用C++/CLI来编译,这样虽然代码是C++的,但是生成的代码还是地道的.net IL代码,然后再进行了一次比较,成绩如下:
 
代码是用的Milo的LCG版本代码可于此下载,编译器是vs2010,测试用的CPU是E6550 2.3GHz
c++ LCG :       42s
C++ LCG 17.365
(g)* C# LCG 59.623
c# LCG:          115s
c++/CLI LCG:  62s
 
从这个例子可以看到,native code与IL code之间的性能差距并不是很大。
 


 
2010/6/24 Jeffrey Zhao <je...@live.com>

qiaojie

unread,
Jun 24, 2010, 2:30:20 AM6/24/10
to pon...@googlegroups.com
2010/6/24 qiaojie <qia...@gmail.com>

L1 Cache miss高是因为这段C#代码里有很多vec, ray之类的临时变量,C#编译器会老老实实的生成这些临时变量,导致运行栈内存占用超过L1大小,而C++编译器的一个很重要的优化是把临时变量通过内联等手段合并优化掉,所以运行栈占用会小很多。不过其实.net不是没有办法优化的,用unsafe代码是可以做到的,只是用C#改起来比较麻烦,所以我偷了个懒,直接把C++代码用C++/CLI来编译,这样虽然代码是C++的,但是生成的代码还是地道的.net IL代码,然后再进行了一次比较,成绩如下:
 
代码是用的Milo的LCG版本代码可于此下载,编译器是vs2010,测试用的CPU是E6550 2.3GHz
c++ LCG :       42s
C++ LCG 17.365
(g)* C# LCG 59.623
c# LCG:          115s
c++/CLI LCG:  62s
 
从这个例子可以看到,native code与IL code之间的性能差距并不是很大。
 
 
 
贴乱了,更正一下:
c++ LCG :       42s

Milo Yip

unread,
Jun 24, 2010, 2:34:42 AM6/24/10
to pon...@googlegroups.com
沒想過用C++/CLI,今晚回去也試試。
其實這樣更能測出在.Net平台上不同語言的性能,減少了一些實驗變數。

Jeffrey Zhao

unread,
Jun 24, 2010, 2:51:15 AM6/24/10
to pon...@googlegroups.com
如果真是这样的话,这说明:
 
1、C#编译器的内联等优化手段做的不够
2、CLR的JIT优化手段做的不够
3、据说Hotspot等JVM的JIT做的优化更彻底,所以Java代码效率也可能会比C#高。
 
为了考证这个结论,看来还是得看静态的人肉分析了。
 
PS:就C#和C++的差距来说,qiaojie的结果和miloyip的结果区别还是挺大的啊。

From: qiaojie
Sent: Thursday, June 24, 2010 2:30 PM
Subject: Re: [TL] 看到一个吵架贴,也来参与一把

qiaojie

unread,
Jun 24, 2010, 2:54:50 AM6/24/10
to pon...@googlegroups.com
比例上差别不大啊,milo的数据在此:
(f)*  C++ LCG  17.365 s
(g)*  C# LCG  59.623s 
当然,他的CPU是i7,比我的要快多了。

2010/6/24 Jeffrey Zhao <je...@live.com>

Milo Yip

unread,
Jun 24, 2010, 2:56:15 AM6/24/10
to pon...@googlegroups.com
文裡忘了提,我用Windows 7 64-bit,但C++版本是用32-bit編譯。

qiaojie

unread,
Jun 24, 2010, 2:56:26 AM6/24/10
to pon...@googlegroups.com
另外要生成并行版本的C#也是非常简单的,milo可以把并行版本的 .NET也加上去做一下比较
 
只要把
for(int y = 0; y < h; y++)
改成
Parallel.For(0, h, (y) =>
...
);
就可以了
 
c++/CLI一样可以这样改,不过我暂时想不起来在C++/CLI里面怎么写lambda了,谁指点一下?
 


 
2010/6/24 Milo Yip <mil...@gmail.com>

qiaojie

unread,
Jun 24, 2010, 2:57:12 AM6/24/10
to pon...@googlegroups.com
我用的也是win7 64bit版,但是全部用32bit x86编译选项编译。


 
2010/6/24 Milo Yip <mil...@gmail.com>

Milo Yip

unread,
Jun 24, 2010, 2:58:06 AM6/24/10
to pon...@googlegroups.com
C# 預設是會編譯成 64-bit 吧?

qiaojie <qia...@gmail.com> 於 2010年6月24日下午2:57 寫道:
我用的也是win7 64bit版,但是全部用32bit x86编译选项编译。

 

qiaojie

unread,
Jun 24, 2010, 3:00:33 AM6/24/10
to pon...@googlegroups.com
我特意改了编译选项的

2010/6/24 Milo Yip <mil...@gmail.com>

Jeffrey Zhao

unread,
Jun 24, 2010, 8:10:02 AM6/24/10
to pon...@googlegroups.com
我测下来时17秒和85秒,真是一件奇怪的事情。

Milo Yip

unread,
Jun 24, 2010, 10:11:29 AM6/24/10
to pon...@googlegroups.com
剛發現C++/CLI可以正常使用OpenMP... 強~
C++/CLI確實比C#快很多,

C++ : C++/CLI  ~= 1 : 1.6
C++ : C# ~= 1 : 2.4
C++/CLI : C# ~= 1 : 2.11 

再更新同一博文好像越來越複雜,可能簡單寫另一篇,也想比一比Java。

Milo Yip

unread,
Jun 24, 2010, 12:08:55 PM6/24/10
to pon...@googlegroups.com
杯具了…… Java 竟然是27秒,C++/CLI 28秒,C# 59秒
不知道甚麼回事。可能是C#版本有問題? Java版本是從C#版本移植過來的。奇怪啊。
再試試.Net Framework 4...

qiaojie

unread,
Jun 24, 2010, 12:28:15 PM6/24/10
to pon...@googlegroups.com
不是有说java对于函数内联的支持更彻底么?
不过对于C#版本的vec,ray用value type未必高效,可以试试改成class再做比较。

2010/6/25 Milo Yip <mil...@gmail.com>

Jeffrey Zhao

unread,
Jun 24, 2010, 12:43:16 PM6/24/10
to pon...@googlegroups.com
其实Hotspot的JIT优化要比CLR彻底(如函数的内联),如果开了-server的话可能会更好,而CLR的优势在于GC。
 
话说这Java没有struct,把C#里的也变成class试试看?struct对GC压力小,但是如果少一些内联或是什么的话,复制操作还是会占不少开销的。而如果每个对象都是用了即抛,那么对于Gen 0的GC压力其实也不大。
 
我刚试了下,用class的时间耗费比struct少20%,不过还是远没达到C++/CLI的水平。如果代码方面没有问题的话,有可能的确是C#的优化不彻底吧?比如内联较少,我看C++代码里面内联的很彻底。
 
还有就是浮点数运算,数学函数的运算等等,总之如果要考察原因的话,都要到微观上去观察了,总之一切还有待琢磨……
 
PS:原本smallpt.cs的16行,return this = this * (1 / Math.Sqrt(x * x + y * y + z * z)); 这个“this =”好像没意义的样子。
 
话说我似乎见过文章说某个科学计算的实验,F#测下来比C++性能高,现在挺让我好奇的,等我睡醒了找找看吧。
 

From: Milo Yip
Sent: Friday, June 25, 2010 12:08 AM
Subject: Re: [TL] 看到一个吵架贴,也来参与一把

qiaojie

unread,
Jun 24, 2010, 12:47:12 PM6/24/10
to pon...@googlegroups.com
把struct改成class提高了20%多的性能,所以说GC慢的理论也是站不住脚的,凡事还是得测试了才知道。


 
2010/6/25 Jeffrey Zhao <je...@live.com>

Milo Yip

unread,
Jun 24, 2010, 12:50:40 PM6/24/10