Java, Python, Ruby, PHP, C 等语言性能对比

2016-08-19 12:59:40 +08:00
 wyk86485481
**代码功能:**循环拼接字符串,并替换子字符串

**硬件环境:**Intel Core2 Duo T7500@2.20Ghz CPU; 2 GB RAM; OS Debian GNU/Linux 2.6.32 i686

### 代码执行时长
![代码运行时长]( https://static.oschina.net/uploads/img/201511/14142908_AExs.png)

**代码性能对比图**
![代码性能对比图]( https://static.oschina.net/uploads/img/201511/14144357_WZxg.png)

最慢: Java gcj (native executable)
较慢: Java (openJDK); Java (Sun); Lua
稍慢: tcl; Javascript (spidermonkey)
较快: Python; Ruby; PHP; C++; Javascript V8; C; Perl5
最快的是 Perl ,最慢的 gcj ,你能接受吗?

### 内存使用情况
![内存使用情况]( https://static.oschina.net/uploads/img/201511/14143131_XRkd.png)

**内存对比图:**
![内存对比图]( https://static.oschina.net/uploads/img/201511/14150514_3YBp.png)

### 测试源码:

C (source); Result: C gcc (Debian 4.4.4-1) 4.4.4

~~~.c
#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

~~~.cpp
#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)

~~~.javascript
#!/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

~~~.java
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

~~~.perl
#!/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
<?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

~~~.python
#!/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

~~~.ruby
#!/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

~~~.lua
#!/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

~~~.tcl
#!/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
~~~

### 结论

各语言随着版本升级,也在不断优化,想要用好每个语言的特性,需要摸透她的脾气,这个需要不断的加深了解。

选语言就像选恋人,情人眼里出西施,你中意的,就是最好的,所以对以上结果别太较真。

转自: http://www.yinqisen.cn/blog-685.html
2078 次点击
所在节点    程序员
2 条回复
EXE
2016-08-19 18:20:47 +08:00
Java 不用 StringBuilder ?
fyibmsd
2016-08-19 20:41:30 +08:00
perl 比 c 还快?处理字符串有加成?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/300403

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX