今天写了个加密的东西,用到了math.Sqrt求质数,发现用的时间很久,先不管下面的例子算法是否有问题,我就写了个demo寻找10 000 000以内的质数个数,原本这个demo是delphi写的,我把它翻译成其他语言,于是我测试了下几个语言的效率:
先用Go语言翻译了下代码:
func main() {
t := time.Now()
sum := 0
for i := 0; i <= 10000000; i++ {
if isPrime(i) == true {
sum = sum + 1
}
}
fmt.Println(sum)
fmt.Println(time.Now().Sub(t))
}
func isPrime(n int) bool {
end := int(math.Sqrt(float64(n)))
for i := 2; i <= end; i++ {
if n%i == 0 {
return false
}
}
return true
}
上面的GO语言输出结果:
664581
40.5965203s
用了40秒左右。
然后我再用网上抄的delphi的这个demo执行了下:
function isPrime(number: integer): boolean;
var
iHalf,iCount:integer;
begin
result:=true;
iHalf:=Round(SQRT(number));
for iCount:=2 to iHalf do
begin
if (number mod iCount)=0 then
begin
result:=false;
break;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var i ,sum:integer;
var m:TDateTime;
begin
m:=((Now)) ;
sum:=0;
for i:=0 To 10000000 do
begin
if isPrime(i)=True then
begin
sum:=sum+1;
end;
end;
Memo1.Lines.Add(TimeToStr(Now-m)) ;
Memo1.Lines.Add(IntToStr(sum))
end;
最终执行结果:
0:00:12
664581
delphi 只用了12秒钟,我感到奇怪,GO语言的执行效率应该快于delphi的啊?
我再用JAVA再次翻译了下:
public class fdfd {
public static void main(String[] args) {
long t = (System.currentTimeMillis());
int sum = 0;
for (int i = 0; i <= 10000000; i++) {
if (isPrime(i)) {
sum = sum + 1;
}
}
System.out.println(sum);
System.out.println((float) (System.currentTimeMillis() - t) / 1000);
}
public static boolean isPrime(int n) {
int end = (int) Math.sqrt(n);
for (int i = 2; i <= end; i++) {
if (n % i == 0)
return false;
}
return true;
}
执行结果:
664581
16.632
JAVA只有了16秒钟。
我用python再次翻译了下
def isPrime(n):
result = True
end = int(math.sqrt(n) + 1)
for i in range(2, end):
if n % i == 0:
result = False
return result
sumC = 0
t = (time.time())
for i in range(10000000):
if isPrime(i):
sumC = sumC + 1
print(sumC)
print((time.time() - t))
发现python很久没有结果,这个也是可以想得到的,毕竟是脚本语言,比不上解释型的语言和编译型的语言。
同时用C#编写了下,大致代码如下
void Button1Click(object sender, EventArgs e)
{ int sum=0;
TimeSpan ts1 = new TimeSpan(DateTime.Now.Ticks);
for (int i=0;i<=10000000;i++){
if (isPrime(i)==true) {
sum=sum+1;
}
}
TimeSpan ts2 = new TimeSpan(DateTime.Now.Ticks);
TimeSpan ts3 = ts1.Subtract(ts2).Duration();
textBox1.Text=sum.ToString()+"\r\n";
textBox1.Text=textBox1.Text+ts3.ToString();
}
bool isPrime(int n) {
int end= (int) Math.Sqrt(n);
for (int i=2;i<=end;i++){
if (n % i==0){
return false;
}
}
return true;
}
}
在net3.5下,c#的最终执行效果:
664581
00:00:16.9267274
16秒,大致和JAVA相当。
按道理来说,GO语言中math.sqrt算法上不会和其他语言相差太多的啊,为什么执行效率差别这么大?因此只能猜测可能GO语言类型转换浪费了大量的时间。