谁都知道Python最大的缺点就是性能差,到底多差网上没有具体数据,今天自己做了一个测试 。
首先要声明一下, 这个简单测试只是通过对阵列的建立、统计的耗时比较, 本以为阵列操作是python的强项,应该差别不大,但结果让人大跌眼镜:建立阵列Python耗时是java的 14倍多, 统计耗时Python是java的24倍多。
硬件环境:
Win8.1 64位、i5 4670K 超到4.2GHZ,内存8G
软件:
python 3.4, JDK 1.6
Phton的:
import time
c_rows=10000
c_cols=10000
lvStart=time.time()
#print(lvStart)
# 建立 [10000][10000]的整数阵列
lvArr=[[] for row in range(1,c_rows+1,1)]
lvRows=len(lvArr)
for row in range(0,lvRows,1):
lvArr[row]=[col for col in range(1,c_cols+1,1)]
lvEnd=time.time()
print("Create lvArray Use:%f" %((lvEnd-lvStart)*1000))
lvStart=time.time()
lvSum=sum(list(map(sum,lvArr)))
lvEnd=time.time()
print("lvArray summary is :%d" %(lvSum))
print("Calculate lvArray Use:%f" %((lvEnd-lvStart)*1000))
Create lvArray Use:3654.559135
lvArray summary is :500050000000
Calculate lvArray Use:962.199926
[Finished in 6.3s]
========
JAVA的:
public class Test {
public static void main(String[] args) {
long lvStart = System.currentTimeMillis();
int[][] lvArr = new int[10000][10000];
for (int row = 0; row < lvArr.length; row++) {
for (int col = 0; col < lvArr[row].length; col++) {
lvArr[row][col] = col + 1;
}
}
long lvEnd = System.currentTimeMillis();
System.out.println(String.format("Create lvArray Use:%d", lvEnd - lvStart));
lvStart = System.currentTimeMillis();
long lvSum = 0;
for (int row = 0; row < lvArr.length; row++) {
for (int col = 0; col < lvArr[row].length; col++) {
lvSum += lvArr[row][col];
}
}
lvEnd = System.currentTimeMillis();
System.out.println(String.format("lvArray summary is :%d", lvSum));
System.out.println(String.format("Calculate lvArray Use:%d", lvEnd-lvStart));
}
}
Create lvArray Use:257
lvArray summary is :500050000000
Calculate lvArray Use:39
原本以为Python会在列表、阵列方法的运算用到并行计算,但没有,感觉很可惜。
C/Delphi这些硬家伙就不对比了,绝对秒得没影。
--------------
再来一段C#的效率:
public static void test()
{
const int arr_length = 10000;
long lvStart = Environment.TickCount;
//Debug.WriteLine(String.Format("Create lvArray Use:{0}", Environment.TickCount - lvStart));
int[][] lvArr = new int[arr_length][];
for (int row = 0; row < arr_length ; row++) {
lvArr[row] = new int[arr_length];
for (int col = 0; col < arr_length ; col++) {
lvArr[row][col] = col + 1;
}
}
long lvEnd = Environment.TickCount;
Debug.WriteLine(String.Format("Create lvArray Use:{0}", lvEnd - lvStart));
lvStart = Environment.TickCount;
long lvSum = 0;
for (int row = 0; row < arr_length; row++)
{
for (int col = 0; col < arr_length; col++)
{
lvSum += lvArr[row][col];
}
}
lvEnd = Environment.TickCount;
Debug.WriteLine(String.Format("lvArray summary is :{0}", lvSum));
Debug.WriteLine(String.Format("Calculate lvArray Use:{0}", lvEnd - lvStart));
}
输出 :
Create lvArray Use:343
lvArray summary is :500050000000
Calculate lvArray Use:172
----------
VC (vs2017编译器), 相同的代码在2015上编译要慢很多
const int arr_length = 10000;
void test(){
CString lvOutStr;
long lv1;
long lvStart = GetTickCount64();
lv1 = lvStart;
//Debug.WriteLine(String.Format("Create lvArray Use:{0}", Environment.TickCount - lvStart));
int* lvArr[arr_length];
for (int row = 0; row < arr_length; row++) {
lvArr[row] = new int[arr_length];
for (int col = 0; col < arr_length; col++) {
*(lvArr[row] + col) = col + 1;
}
}
long lvEnd = GetTickCount64();
lvOutStr.Format(_T("Create lvArray Use:%d\n"), lvEnd - lvStart);
OutputDebugString(lvOutStr);
lvStart = GetTickCount64();
INT64 lvSum = 0;
for (int row = 0; row < arr_length; row++)
{
for (int col = 0; col < arr_length; col++)
{
lvSum += *(lvArr[row] + col);
}
}
for (int row = 0; row < arr_length; row++) {
delete[] lvArr[row];
}
lvEnd = GetTickCount64();
lvOutStr.Format(_T("lvArray summary is :%lld\n"), lvSum);
OutputDebugString(lvOutStr);
lvOutStr.Format(_T("Calculate lvArray Use:%d\n"), lvEnd - lvStart);
OutputDebugString(lvOutStr);
}
Create lvArray Use:94
lvArray summary is :500050000000
Calculate lvArray Use:62
codetyphon(lazarus, gcc 64编译器)
type
TarrInt = array of pinteger;
procedure TForm1.Button1Click(Sender: TObject);
var
lvStart, lvEnd: LongWord;
lvArr: TArrInt;
lvSize: integer;
col, row: integer;
lvSum: UInt64;
lvVal:PInteger;
lvOut:string;
begin
lvSize := 10000;
{getmem(lvOut,1);
fillchar(lvOut^,0,1);}
lvOut:='';
lvStart := GetTickCount;
setLength(lvArr, lvSize);
for row := 0 to lvSize - 1 do
begin
getmem(lvArr[row], sizeof(integer) * lvSize);
lvVal:=lvArr[row] ;
for col := 0 to lvSize - 1 do
begin
//lvVal:=integer(lvVal)+1;
lvVal^ := col + 1;
Inc(lvVal);
end;
end;
lvEnd := GetTickCount();
//lvOut.add(Format('Create lvArray Use:%d', [lvEnd - lvStart]));
lvOut:=lvOut+Format('Create lvArray Use:%d'#13#10, [lvEnd - lvStart]);
lvStart := GetTickCount;
lvSum := 0;
for row := 0 to lvSize - 1 do
begin
lvVal:=lvArr[row] ;
for col := 0 to lvSize - 1 do
begin
lvSum := lvSum + lvVal^;
Inc(lvVal);
end;
end;
for row := 0 to lvSize - 1 do
begin
freemem(lvArr[row],sizeof(integer) * lvSize);
end;
lvEnd := GetTickCount();
//lvOut.add(Format('lvArray summary is :%d', [lvSum]));
lvOut:=lvOut+Format('lvArray summary is :%d'#13#10, [lvSum]);
lvOut:=lvOut+Format('Calculate lvArray Use:%d'#13#10, [lvEnd - lvStart]);
memo1.Text:=lvOut;
//StrDispose(lvOut);
//memo1.Lines.Text := lvOut.Text;
end;
输出:
Create lvArray Use:125
lvArray summary is :500050000000
Calculate lvArray Use:79
Delphi EX10.2(64位编译器),
type
TarrInt = array of pinteger;
procedure TForm1.Button1Click(Sender: TObject);
var
lvStart, lvEnd: cardinal;
lvArr: TArrInt;
lvSize: integer;
col, row: integer;
lvSum: UInt64;
lvVal:PInteger;
lvOut:pchar;
begin
lvSize := 10000;
{getmem(lvOut,1);
fillchar(lvOut^,0,1);}
lvOut:=strnew('');
lvStart := GetTickCount;
setLength(lvArr, lvSize);
for row := 0 to lvSize - 1 do
begin
getmem(lvArr[row], sizeof(integer) * lvSize);
lvVal:=lvArr[row] ;
for col := 0 to lvSize - 1 do
begin
//lvVal:=integer(lvVal)+1;
lvVal^ := col + 1;
Inc(lvVal);
end;
end;
lvEnd := GetTickCount();
//lvOut.add(Format('Create lvArray Use:%d', [lvEnd - lvStart]));
StrCat(lvOut,pchar(Format('Create lvArray Use:%d'#13#10, [lvEnd - lvStart])));
lvStart := GetTickCount;
lvSum := 0;
for row := 0 to lvSize - 1 do
begin
lvVal:=lvArr[row] ;
for col := 0 to lvSize - 1 do
begin
lvSum := lvSum + lvVal^;
Inc(lvVal);
end;
end;
for row := 0 to lvSize - 1 do
begin
freemem(lvArr[row]);
end;
lvEnd := GetTickCount();
//lvOut.add(Format('lvArray summary is :%d', [lvSum]));
strcat(lvOut,pchar(Format('lvArray summary is :%d'#13#10, [lvSum])));
strcat(lvOut,pchar(Format('Calculate lvArray Use:%d'#13#10, [lvEnd - lvStart])));
memo1.Text:=strpas(lvOut);
StrDispose(lvOut);
//memo1.Lines.Text := lvOut.Text;
end;
输出 :
Create lvArray Use:104
lvArray summary is :500050000000
Calculate lvArray Use:63
几种编译器对10000X10000的阵列进行内存分配/初始化及运算, 所有测试都在默认参数下编译/运行, release模式, 结果对比如下:
编译器 | 性能(单位ms) |
VC(64位) | 156 |
Delphi EX Tokyo(64位) | 167 |
Delphi XE7(64位) | 172 |
CodeTyphon/Lazarus(gcc编译器,64位) | 203 |
JAVA(64位) | 296 |
C#(vs2017,64位) | 512 |
Delphi 7(32位) | 532 |
python | 4617 |
Delphi7编译质量并不差, 输在内存管理器的效率上.