文档章节

golang语言中的math库中效率低下,可能是类型转换花费了大量时间?

大洋的顶端
 大洋的顶端
发布于 2017/10/26 05:25
字数 681
阅读 567
收藏 1

今天写了个加密的东西,用到了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语言类型转换浪费了大量的时间。


 

© 著作权归作者所有

大洋的顶端
粉丝 16
博文 30
码字总数 13805
作品 0
广州
私信 提问
加载中

评论(14)

众思越
众思越
i3 g2030 win7 用楼主的代码只用了6秒
众思越
众思越
用楼主的代码,我这只用了6秒
newzai
newzai
pprofile 分析一下cpu就知道了
五杀联盟
五杀联盟
改成32位int 和java一样快 老铁
真J8难注册
你这是在炫耀吗
养由基
你的写法不太符合Go的思想。
package main

import (
  "fmt"
)

func generate(ch chan<- int) {
  for i := 2; ; i++ {
    ch <- i // Send 'i' to channel 'ch'.
  }
}

func filter(src <-chan int, dst chan<- int, prime int) {
  for i := range src { // Loop over values received from 'src'.
    if i%prime != 0 {
      dst <- i // Send 'i' to channel 'dst'.
    }
  }
}

func sieve() {
  ch := make(chan int) // Create a new channel.
  go generate(ch) // Start generate() as a subprocess.
  var iCount int32
  for {
    prime := <-ch
    fmt.Print(prime, "\n")
    ch1 := make(chan int)
    go filter(ch, ch1, prime)
    ch = ch1
    if iCount > 9999 {
      break
    }
    iCount++
  }
}

func main() {
  sieve()
}


这个才是Go思想的写法
狂战暴走
狂战暴走
golang 1.7.3 要16s
小马哥啊
小马哥啊
I7 window10 golang 1.9

22秒,使用int32 代替 int 后 9.4秒

难道我使用的是假的 I7 ?
李嘉图
李嘉图
cpu 和 内存,go的版本和系统的版本也不说,这样不严谨
guanly
guanly

引用来自“OSC_Pdhdcl”的评论

仔细看看你java实现的类型定义,
确实,把类型换成double慢得不要不要的
golang cgo 使用总结(一)

CGO 提供了 golang 和 C 语言相互调用的机制。某些第三方库可能只有 C/C++ 的实现,完全用纯 golang 的实现可能工程浩大,这时候 CGO 就派上用场了。可以通 CGO 在 golang 在调用 C 的接口,...

echojson
04/18
0
0
五大理由从 Python 转到 Go 语言

“ Python 是非常强大的,特别是 Python3 有了异步功能,但是 GO 将完全取代它在大企业中的存在…” 如果你真正理解了引号中的话,你可能会去尝试 Go 编程语言。我认为 Go 是很简单的编程语言...

oschina
2017/04/10
12.1K
120
golang利用reflect包实现struct与params自动绑定

前言 因为 golang 静态强类型语言特性以及没有很好的泛型支持导致在用 go 写 web 服务的时候,总会因为要对 http params 的解析和类型转换上要花很多时间,并且这会让代码显得很冗余,那有什...

大糊涂
2018/05/20
0
0
把 Python 源码自动转化为 Go 源码

 Interesting idea!   https://groups.google.com/d/msg/golang-china/okoCj4pwiEA/S03ewhboTeoJ   See translation:   https://translate.google.com/translate?sl=auto&tl=en&js=y......

taohongfei
2014/05/26
17
0
为什么要选择Python语言实现机器学习算法

基于以下三个原因,我们选择Python作为实现机器学习算法的编程语言:(1) Python的语法清晰;(2) 易于操作纯文本文件;(3) 使用广泛,存在大量的开发文档。 可执行伪代码 Python具有清晰的语法...

生气的散人
2013/06/04
1K
2

没有更多内容

加载失败,请刷新页面

加载更多

《精进》的读后感作文2600字

《精进》的读后感作文2600字: 首先,我想先分享我读这本书的过程,我是一名大一的学生,在我高考完的暑假,有一次一位知乎用户的朋友推荐了这本书。当时我看了这本书的封面,有一句话非常的...

原创小博客
4分钟前
0
0
亿万pv的混合云规划实施

基础服务: keepalive,lvs,nginx,dns,ntp,redis集群,yum仓库,web资源 网络高可用 防火墙冗余,交换机堆叠 专线互联 物理机虚拟化 VMware vcenter/ Proxmox...

以谁为师
26分钟前
0
0
聊聊dubbo的LRUCache

序 本文主要研究一下dubbo的LRUCache LRUCache dubbo-2.7.2/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LRUCache.java public class LRUCache<K, V> extends LinkedHashMap<......

go4it
28分钟前
0
0
前端知识点总结——H5

前端知识点总结——H5 1.html5新特性 (1)新的语义标签 (2)增强型表单* (3)音频和视频 (4)Canvas绘图 (5)SVG绘图 (6)地理定位 (7)拖动API (8)Web Worker (9)Web Storage (10)Web Socket 2.增强...

智云编程
31分钟前
0
0
微服务之架构技术选型与设计

本文主要介绍了架构技术选型与设计-微服务选型,Spring cloud 实现采用的技术,希望对您的学习有所帮助。 架构技术选型与设计-DUBBODubbo,是阿里巴巴服务化治理的核心框架,并被广泛应用于阿...

别打我会飞
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部