【小测试】fastcgo 调用 c 代码

发布时间 2023-09-26 13:26:29作者: ahfuzhang

作者:张富春(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()
}