为什么CGO的表现是如此之慢?是有什么错我的测试code? [英] Why cgo's performance is so slow? is there something wrong with my testing code?

查看:3019
本文介绍了为什么CGO的表现是如此之慢?是有什么错我的测试code?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在做一个试验:比较CGO和纯转到功能excecution时间运行各100万次。相比Golang功能的CGO功能需要较长的时间,我很困惑这个结果。我的测试code是:

I'm doing a test: compare excecution times of cgo and pure Go functions run 100 million times each. The cgo function takes longer time compared to the Golang function, and I am confused with this result. My testing code is:

package main

import (
    "fmt"
    "time"
)

/*
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void show() {

}

*/
// #cgo LDFLAGS: -lstdc++
import "C"

//import "fmt"

func show() {

}

func main() {
    now := time.Now()
    for i := 0; i < 100000000; i = i + 1 {
        C.show()
    }
    end_time := time.Now()

    var dur_time time.Duration = end_time.Sub(now)
    var elapsed_min float64 = dur_time.Minutes()
    var elapsed_sec float64 = dur_time.Seconds()
    var elapsed_nano int64 = dur_time.Nanoseconds()
    fmt.Printf("cgo show function elasped %f minutes or \nelapsed %f seconds or \nelapsed %d nanoseconds\n",
        elapsed_min, elapsed_sec, elapsed_nano)

    now = time.Now()
    for i := 0; i < 100000000; i = i + 1 {
        show()
    }
    end_time = time.Now()

    dur_time = end_time.Sub(now)
    elapsed_min = dur_time.Minutes()
    elapsed_sec = dur_time.Seconds()
    elapsed_nano = dur_time.Nanoseconds()
    fmt.Printf("go show function elasped %f minutes or \nelapsed %f seconds or \nelapsed %d nanoseconds\n",
        elapsed_min, elapsed_sec, elapsed_nano)

    var input string
    fmt.Scanln(&input)
}

和结果是:

cgo show function elasped 0.368096 minutes or 
elapsed 22.085756 seconds or 
elapsed 22085755775 nanoseconds

go show function elasped 0.000654 minutes or 
elapsed 0.039257 seconds or 
elapsed 39257120 nanoseconds

结果表明调用C函数比转到功能慢。是不是有什么毛病我的测试code?

The results show that invoking the C function is slower than the Go function. Is there something wrong with my testing code?

我的系统是:MAC OS X 10.9.4(13E28)

My system is : mac OS X 10.9.4 (13E28)

推荐答案

当你已经发现,存在通过调用CGO C / C ++ code相当高的开销。因此,在一般情况下,你是最好关闭试图降低CGO的叫你做的次数。对于上述的例子,而不是在一个循环反复调用CGO函数它可能是有意义的向下移动环为C

As you've discovered, there is fairly high overhead in calling C/C++ code via CGo. So in general, you are best off trying to minimise the number of CGo calls you make. For the above example, rather than calling a CGo function repeatedly in a loop it might make sense to move the loop down to C.

有一些可以突破C $ C $的C多件的期望的Go运行时是如何设置它的线程方面:

There are a number of aspects of how the Go runtime sets up its threads that can break the expectations of many pieces of C code:


    够程在一个相对较小的堆栈上运行,通过分段栈(旧版本)或复制(新版本)处理堆栈增长

  1. 由Go运行时创建的线程可能无法与的libpthread 的线程本地存储实现正确的交互。

  2. Go运行时的UNIX信号处理程序可能会与传统的C或C ++ code干扰。

  3. 转到重用操作系统线程同时运行多个够程。如果C code称为阻塞系统调用或以其他方式垄断了线程,它可能损害其它够程。

  1. Goroutines run on a relatively small stack, handling stack growth through segmented stacks (old versions) or by copying (new versions).
  2. Threads created by the Go runtime may not interact properly with libpthread's thread local storage implementation.
  3. The Go runtime's UNIX signal handler may interfere with traditional C or C++ code.
  4. Go reuses OS threads to run multiple Goroutines. If the C code called a blocking system call or otherwise monopolised the thread, it could be detrimental to other goroutines.

由于这些原因,CGO挑选一个单独的线程设置与传统的堆运行C code的安全方法。

For these reasons, CGo picks the safe approach of running the C code in a separate thread set up with a traditional stack.

如果您是从如Python语言的地方并不少见在C重写code热点,以此来加快你会失望的程序来。但在同一时间,有相当于在C和围棋code之间的性能更小的差距。

If you are coming from languages like Python where it isn't uncommon to rewrite code hotspots in C as a way to speed up a program you will be disappointed. But at the same time, there is a much smaller gap in performance between equivalent C and Go code.

在一般我保留CGO与现有的库接口,可能与小C的包装功能,可以减少我需要去拨打电话的次数。

In general I reserve CGo for interfacing with existing libraries, possibly with small C wrapper functions that can reduce the number of calls I need to make from Go.

这篇关于为什么CGO的表现是如此之慢?是有什么错我的测试code?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆