代码功能:循环拼接字符串,并替换子字符串
硬件环境:Intel Core2 Duo T7500@2.20Ghz CPU; 2 GB RAM; OS Debian GNU/Linux 2.6.32 i686
代码执行时长
代码性能对比图
最慢: Java gcj (native executable) 较慢: Java (openJDK); Java (Sun); Lua 稍慢: tcl; Javascript (spidermonkey) 较快: Python; Ruby; PHP; C++; Javascript V8; C; Perl5 最快的是Perl,最慢的gcj,你能接受吗?
内存使用情况
内存对比图:
测试源码:
C (source); Result: C gcc (Debian 4.4.4-1) 4.4.4
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> int main(){ setbuf(stdout,NULL); //disable output buffering char *str=malloc(8); strcpy(str,"abcdefgh"); str=realloc(str,strlen(str)+8); strcat(str,"efghefgh"); //sprintf(str,"%s%s",str,"efghefgh"); int imax=1024/strlen(str)*1024*4; printf("%s","exec.tm.sec\tstr.length\n"); //fflush(stdout); time_t starttime=time(NULL); char *gstr=malloc(0); int i=0; char *pos; int lngth; char *pos_c=gstr; int str_len=strlen(str); while(i++ < imax+1000){ lngth=strlen(str)*i; gstr=realloc(gstr,lngth+str_len); strcat(gstr,str); //sprintf(gstr,"%s%s",gstr,str); pos_c+=str_len; pos=gstr; while(pos=strstr(pos,"efgh")){ memcpy(pos,"____",4); } if(lngth % (1024*256)==0){ printf("%dsec\t\t%dkb\n",time(NULL)-starttime,lngth/1024); //fflush(stdout); } } //printf("%s\n",gstr); }
C++ (source) Result: C++ g++ (Debian 4.4.3-7) 4.4.3
#include <iostream> #include <string> #include <time.h> using namespace std; main () { string str = "abcdefgh"; str += "efghefgh"; int imax = 1024 /str.length() * 1024 *4; time_t currentTime = time(NULL); cout << "exec.tm.sec\tstr.length" << endl; string find= "efgh"; string replace ="____"; string gstr; int i=0; int length; // int end=0; // size_t end=0; while(i++ < imax +1000){ gstr += str; gstr = gstr; size_t start, sizeSearch=find.size(), end=0; while((start=gstr.find(find,end))!=string::npos){ end=start+sizeSearch; gstr.replace(start,sizeSearch,replace); } length = str.length()*i; if((length%(1024 * 256))==0){ cout << time(NULL) - currentTime << "sec\t\t" << length/1024 << "kb" << endl; } } // cout << gstr << endl; return 0; }
Javascript (source); Results: Javascript (Spidermonkey – Mozilla) 1.8.0 pre-release 1 2007-10-03,
Javascript (V8 – Chrome)
#!/usr/local/bin/js var str = "abcdefgh"+"efghefgh"; var imax = 1024 / str.length * 1024 * 4; var time = new Date(); print("exec.tm.sec\tstr.length"); var gstr = ""; var i=0; var lngth; while (i++ < imax+1000) { gstr += str; gstr = gstr.replace(/efgh/g, "____"); lngth=str.length*i; if ((lngth % (1024*256)) == 0) { var curdate=new Date(); print(parseInt(((curdate.getTime()-time.getTime())/1000))+"sec\t\t"+lngth/1024+"kb"); } }
Java (source) Results: Java (OpenJDK) “1.6.0 18”,
Java (Sun) “1.6.0 16”,
Java (gcj) (Debian 4.4.3-1) 4.4.3
public class java_test { public static final void main(String[] args) throws Exception { String str = "abcdefgh"+"efghefgh"; int imax = 1024 / str.length() * 1024 * 4; long time = System.currentTimeMillis(); System.out.println("exec.tm.sec\tstr.length\tallocated memory:free memory:memory used"); Runtime runtime = Runtime.getRuntime(); System.out.println("0\t\t0\t\t"+runtime.totalMemory()/1024 +":"+ runtime.freeMemory()/1024+":"+(runtime.totalMemory()-runtime.freeMemory())/1024); String gstr = ""; int i=0; int lngth; while (i++ < imax+1000) { gstr += str; gstr = gstr.replaceAll("efgh", "____"); lngth=str.length()*i; if ((lngth % (1024*256)) == 0) { System.out.println(((System.currentTimeMillis()-time)/1000)+"sec\t\t"+lngth/1024+"kb\t\t"+runtime.totalMemory()/1024+":"+runtime.freeMemory()/1024+":"+(runtime.totalMemory()-runtime.freeMemory())/1024); } } } }
Perl5 (source); Result: This is perl, v5.10.1
#!/usr/bin/perl $|=1; #disable output buffering, this is necessary for proper output through pipe my $str='abcdefgh'.'efghefgh'; my $imax=1024/length($str)*1024*4; # 4mb my $starttime=time(); print "exec.tm.sec\tstr.length\n"; my $gstr=''; my $i=0; while($i++ < $imax+1000){ #adding 1000 iterations to delay exit. This will allow to capture memory usage on last step $gstr.=$str; $gstr=~s/efgh/____/g; my $lngth=length($str)*$i; ## my $lngth=length($gstr); # Perhaps that would be a slower way print time()-$starttime,"sec\t\t",$lngth/1024,"kb\n" unless $lngth % (1024*256); #print out every 256kb }
PHP (source); Result: PHP 5.3.1-5 with Suhosin-Patch (cgi-fcgi)
<?php $str="abcdefgh"."efghefgh"; $imax=1024/strlen($str)*1024*4; # 4mb $starttime=time(); print("exec.tm.sec\tstr.length\n"); $gstr=''; $i=0; while($i++ < $imax+1000){ $gstr.=$str; $gstr=preg_replace('/efgh/','____',$gstr); $lngth=strlen($str)*$i; if($lngth % (1024*256)==0){ print (time()-$starttime."sec\t\t".($lngth/1024)."kb\n"); } } ?>
Python3 (source); Result: Python 3.1.3
#!/usr/bin/python3 -u import re import time import sys str='abcdefgh'+'efghefgh' imax=1024/len(str)*1024*4 # 4mb starttime=time.time(); print "exec.tm.sec\tstr.length" sys.stdout.flush() gstr='' i=0 while (i < imax+1000): i=i+1 gstr+=str gstr=re.sub('efgh','____',gstr) lngth=len(str)*i if(lngth % (1024*256) == 0): print int(time.time()-starttime),"sec\t\t",(lngth/1024),"kb" sys.stdout.flush()
Ruby (source); Result: ruby 1.8.7
#!/usr/bin/ruby $stdout.sync=true; str='abcdefgh'+'efghefgh'; imax=1024/str.length*1024*4; # 4mb starttime=Time.new; print("exec.tm.sec\tstr.length\n"); gstr=''; i=0; while i < imax+1000 i=i+1; gstr+=str; gstr=gstr.gsub(/efgh/, "____") lngth=str.length*i; if(lngth % (1024*256)==0) print(((Time.new-starttime).ceil).to_s+"sec\t\t",(lngth/1024).to_s,"kb\n"); end end #puts gstr;
Lua (source); Result: Lua 5.1.4
#!/usr/bin/lua io.stdout:setvbuf "no"; -- io.flush(); str='abcdefgh'..'efghefgh'; imax=1024/string.len(str)*1024*4; -- 4mb starttime=os.time(); print "exec.tm.sec\tstr.length"; gstr=''; i=0; while i < imax+1000 do i=i+1; gstr=gstr..str; gstr=string.gsub(gstr,"efgh","____"); lngth=string.len(str)*i; if(math.mod(lngth,1024*256)==0) then print(os.time()-starttime.."sec\t\t"..(lngth/1024).."kb"); end end
tcl (source); Result: tcl 8.4.19
#!/usr/bin/tclsh set str "abcdefgh" append str "efghefgh" set imax [expr {1024/[string length $str]*1024*4}] set starttime [clock clicks -milliseconds] puts "exec.tm.sec\tstr.length"; set gstr "" set i 0 while {$i<[expr {$imax+1000}]} { incr i append gstr $str; regsub -all {efgh} $gstr ____ gstr set lngth [expr {[string length $str]*$i}] if {[expr {$lngth % (1024*256)}] == 0} { puts "[expr int([expr [clock clicks -milliseconds] - $starttime] / 1000)]sec\t\t[expr {$lngth/1024}]kb" } } exit
结论
各语言随着版本升级,也在不断优化,想要用好每个语言的特性,需要摸透她的脾气,这个需要不断的加深了解。
选语言就像选恋人,情人眼里出西施,你中意的,就是最好的,所以对以上结果别太较真。
java用stringbuilder测试,性能高很多