作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
找到了一个项目,通过汇编的方式来 call c函数,相比 cgo 会快很多。
究竟多块,我做了个测试:
- 测试的 api: getpid()
- 直接 syscall 的版本:284.7333 ns / op
- cgo的版本:579.0323 ns / op
- fastcgo 版本:290.9751 ns / op
可见 fastcgo 只比直接 syscall 慢一点点,当需要频繁的系统调用的场合,可以用 fastcgo 来代替 cgo.
下面是测试代码:
package main
/*
#define _GNU_SOURCE
#include <sched.h>
// getpid()
*/
import "C"
import (
"fmt"
"log"
"os"
"runtime"
"strconv"
"strings"
"time"
"unsafe"
"github.com/petermattis/fastcgo"
)
func GetPidFast() int {
var ret C.int
fastcgo.UnsafeCall4(C.getpid, uint64(uintptr(unsafe.Pointer(&ret))), 0, 0, 0)
return int(ret)
}
const runTimes = 10000000
func getpidTest() {
now := time.Now()
for i := 0; i < runTimes; i++ {
_ = os.Getpid()
}
fmt.Println("os.Getpid(): ", time.Since(now).Microseconds())
}
func getpidCgoTest() {
now := time.Now()
for i := 0; i < runTimes; i++ {
_ = C.getpid()
}
fmt.Println("C.getpid(): ", time.Since(now).Microseconds())
}
func getpidFastCgoTest() {
now := time.Now()
for i := 0; i < runTimes; i++ {
_ = GetPidFast()
}
fmt.Println("GetPidFast(): ", time.Since(now).Microseconds())
}
func main() {
runtime.GOMAXPROCS(1)
getpidTest()
getpidFastCgoTest()
getpidCgoTest()
}