猿问

在 Go 中以 GMP 风格的性能处理大量数据

我正在学习 Go 并开始使用该math/big包来处理任意长度的整数。


我写了这个程序来计算第 n 个斐波那契数:(去掉了imports):


func main() {

    imax, _ := strconv.Atoi(os.Args[1])

    var a, b, c big.Int

    a.SetUint64(0)

    b.SetUint64(1)

    for i := 0; i < imax; i++ {

        c.Set(&b)

        b.Add(&b, &a)

        a.Set(&c)

    }

    fmt.Println(a.String())

}

这是 C 程序的代码:


int main(int argc, char** argv)

{

    int imax = atoi(argv[1]);


    mpz_t a, b, c;

    mpz_inits(a, b, c, NULL);

    mpz_set_ui(a, 0);

    mpz_set_ui(b, 1);


    int i = 0;

    for (i = 0; i < imax; i++) {

        mpz_swap(a, b);

        mpz_add(b, a, b);

    }


    char* astr = NULL;

    astr = mpz_get_str(NULL, 10, a);

    printf("%s\n", astr);


    return EXIT_SUCCESS;

}

Go 程序在 0.1 秒(平均)内计算术语 100,000,而使用 GMP 库的 C 等效项仅在 0.04 秒内运行。那慢了两倍。


有没有办法在我的 Go 程序中获得相同的性能?


胡子哥哥
浏览 228回答 2
2回答

慕尼黑的夜晚无繁华

一般来说,GMP 速度更快,因为它是为性能而设计的。在幕后,您可能会发现它部分是用汇编编写的,这减少了函数的调用开销,可能会使用一些 CPU 指令ADX,诸如此类。如果您关心性能,那么您可以使用mpz_fib_ui例程,这会更快,因为它可以从一些数学技巧中获益。您的问题的直接答案可能是使用一些 Go 对 GMP 的绑定。

心有法竹

不要打印到标准输出,它很慢。你得到这个代码的结果是什么?package mainimport (&nbsp; &nbsp; "math/big"&nbsp; &nbsp; "os"&nbsp; &nbsp; "strconv")func main() {&nbsp; &nbsp; max, err := strconv.Atoi(os.Args[1])&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; panic(err)&nbsp; &nbsp; }&nbsp; &nbsp; a, b := big.NewInt(0), big.NewInt(1)&nbsp; &nbsp; for i := 0; i < max; i++ {&nbsp; &nbsp; &nbsp; &nbsp; a.Add(a, b)&nbsp; &nbsp; &nbsp; &nbsp; a, b = b, a&nbsp; &nbsp; }}Go 不是手工编写的汇编代码。您的 100,000 值对于可靠的基准测试来说太小了。使用 1,000,000 或其他至少运行 10 秒的值。
随时随地看视频慕课网APP

相关分类

Go
我要回答