實(shí)際上不是全面測(cè)試性能。應(yīng)該這么說:使用一個(gè)你熟悉的語(yǔ)言,用它寫出一個(gè)高效的版本(做下面那件事)。
不小心讀到一個(gè)帖子:http://blog.vckbase.com/jzhang/archive/2006/03/28/18807.html
看到C++竟然被比下去了,自然不是很舒服,畢竟C++對(duì)于C并沒有太大的性能上的降低,而python是C寫的(指Cpython實(shí)現(xiàn)),自然不會(huì)高過C。(廢話,C基本上接近匯編效率了)
可惜C++又很難找出這么高效的實(shí)現(xiàn),STL效率還是低了些(為什么?一直以為它很高效,用得比較放心)。最近一直比較關(guān)注D語(yǔ)言,于是用D語(yǔ)言來測(cè)試一下。代碼如下:
?1?import?std.stdio;
?2?import?std.string;
?3?import?std.perf;
?4?
?5?int?main(char[][]?argv)
?6?{
?7???if?(argv.length?<?3)?{
?8?????writefln("Wrong?arguments");
?9?????return?1;
10???}
11?
12???const?int?READ_SIZE?=?1024;
13?
14???FILE*?fin?=?fopen(argv[1],?"r");
15???FILE*?fout?=?fopen(argv[2],?"w");
16???char?buffer[READ_SIZE];
17???int[char[]]?emails;
18?
19???PerformanceCounter?counter?=?new?PerformanceCounter();
20???counter.start();
21???while?(!feof(fin)){
22?????fgets(cast(char*)buffer,?READ_SIZE,?fin);
23?????char[]?email?=?toString(cast(char*)buffer);
24?????if?(!(email?in?emails)){
25???????emails[toString(buffer)]?=?0;
26???????fputs(cast(char*)email,?fout);
27?????}
28???}
29?
30???fclose(fout);
31???fclose(fin);
32???counter.stop();
33?
34???writefln(counter.milliseconds());
35???return?0;
36?}
37?
沒加fopen失敗處理。
測(cè)試結(jié)果在我的機(jī)器上耗時(shí)只有python版本的1/3,我看到其它網(wǎng)友的C++實(shí)現(xiàn)最好成績(jī)也不過1/2,由于是D是C語(yǔ)言所寫,測(cè)試使用的又是C庫(kù),自然可以認(rèn)為C語(yǔ)言還是比較高效的。
上面的D語(yǔ)言代碼里調(diào)用了toString,把char*轉(zhuǎn)為char[],它的源代碼如下:
char[]?toString(char?*s)
{
????return?s???s[0?..?strlen(s)]?:?cast(char[])null;
}
如果s[0 .. strlen(s)]產(chǎn)生了復(fù)制的話,應(yīng)該是會(huì)影響性能的。char[]對(duì)象是受GC管理的,應(yīng)該會(huì)復(fù)制一份。這種情況下還能有如此高的效率,的確很不錯(cuò)。
不過python的性能讓我感覺很吃驚,以前只測(cè)試過字符串連接,感覺比較高效。
寫了一個(gè)完成一樣功能的ruby程序,耗時(shí)接近python版本的2倍,當(dāng)然由于對(duì)它不是很熟,可能寫得不夠高效。
?1?emails?=?Hash.new
?2?
?3?start?=?Time.now
?4?fout?=?open('email-2-new1.txt',?'w')
?5?open('email-2.txt').each?do?|line|
?6???if?!emails.has_key??line
?7?????emails[line]?=?0
?8?????fout?<<?line
?9???end
10?end
11?puts?Time.now?-?start
12?
正如某網(wǎng)友所說,這個(gè)程序的瓶頸在于IO,拿來作性能上的比較或許是不合適的。從語(yǔ)言效率上來講,自然是C++和D相當(dāng),可能會(huì)比D高,python應(yīng)該會(huì)低很多。但在很多情況下,衡量效率不光是語(yǔ)言本身,還有庫(kù),沒有庫(kù)的語(yǔ)言是沒什么吸引力的。python是一種很“慢”的語(yǔ)言,相對(duì)C/C++來說,不過它是一門實(shí)用性的語(yǔ)言,所以它為一些特定用法做了優(yōu)化,取得了不錯(cuò)的成績(jī)。C++是一門通用語(yǔ)言,或許太注重語(yǔ)言的性能了,忽略了庫(kù),導(dǎo)致庫(kù)把性能給拉下來了。這種情況下,有人評(píng)測(cè)java和C++的性能,結(jié)果是java要高,自然是不那么讓人驚奇的了。可是如果標(biāo)準(zhǔn)庫(kù)都這么慢,那還能指望什么呢?
當(dāng)然也并沒有證明STL就特別慢,也可能是使用不正確。
只是剛好看到這個(gè)比較,忍不住參與一下,切勿當(dāng)真。