Bignum实现有效添加小整数

时间:2009-12-02 07:33:28

标签: c++ python bignum gmp arbitrary-precision

我一直在使用python的原生bignums算法,并决定尝试通过将其转换为C ++来加速它。当我使用long long时,C ++比python快约100倍,但是当我在C ++中使用GMP绑定时,它只比python快10倍(对于适合长long的相同情况)。

是否有更好的bignum实施来进行大量小额添加?例如,我们有一个很大的数字N我们将添加很多小+1,+ 21,+ 1等等,并且每隔一段时间再添加一个大数字M?

3 个答案:

答案 0 :(得分:2)

GMP图书馆本身有一个fast short integer add to MPZ routine

void mpz_add_ui (mpz_t rop, mpz_t op1, unsigned long int op2)

我不知道gmpy是否使用了它,但是如果它确实尝试将一个普通的python int添加到mpz vs将mpz添加到mpz并查看它是否更快。

修改

我尝试了一些基准测试,发现它没有任何区别

$ python -m timeit -c 'from gmpy import mpz
> a=mpz(10**1000)' 'a+1'
100000 loops, best of 3: 5.4 usec per loop

$ python -m timeit -c 'from gmpy import mpz
a=mpz(10**1000); b=mpz(1)' 'a+b'
100000 loops, best of 3: 5.5 usec per loop

所以我猜gmpy并没有使用mpz_add_ui,因为我真的希望它会更快。

答案 1 :(得分:0)

你做过剖析吗? Python和C ++ 整个应用程序。所以你知道你真的需要额外的速度。

尝试Python 3k它现在实现了任意长度的整数!

答案 2 :(得分:0)

(注意:我帮助维护GMPY,并且我在最新版本中实现了很多优化。)

GMPY v1.11在向mpz添加一个小数字时使用mpz_add_ui。使用小数字时,最新版本的GMPY比以前的版本快25%左右。

With GMPY 1.04
$ py26 -mtimeit -s "import gmpy;a=gmpy.mpz(10**1000)" "a+1"
10000000 loops, best of 3: 0.18 usec per loop
$ py26 -mtimeit -s "import gmpy;a=gmpy.mpz(10**1000);b=gmpy.mpz(1)" "a+b"
10000000 loops, best of 3: 0.153 usec per loop

With GMPY 1.11
$ py26 -mtimeit -s "import gmpy;a=gmpy.mpz(10**1000)" "a+1"
10000000 loops, best of 3: 0.127 usec per loop
$ py26 -mtimeit -s "import gmpy;a=gmpy.mpz(10**1000);b=gmpy.mpz(1)" "a+b"
10000000 loops, best of 3: 0.148 usec per loop

由于将Python int转换为long并调用mpz_add_ui比将Python int转换为mpz更快,因此具有适度的性能优势。如果在长时间内调用GMP函数与本机操作相比会有10倍的性能损失,我不会感到惊讶。

你可以将几个小数字累积成一个长的长数并一次将它们添加到你的大数字中吗?