Bignum 实现,具有小整数的高效加法

发布于 2024-08-12 16:52:54 字数 248 浏览 7 评论 0原文

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

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

I have been using python's native bignums for an algorithm and decided to try and speed it up by converting it to C++. When I used long longs, the C++ was about 100x faster than the python, but when I used GMP bindings in C++, it was only 10x faster than the python (for the same cases that fit in long longs).

Is there a better bignum implementation for doing a large number of small additions? For example, we have a big number N we'll be adding a lot of little +1, +21, +1, etc. and every once and a while adds another big number M?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

落花浅忆 2024-08-19 16:52:54

GMP 库本身有一个快速短整数添加到 MPZ 例程

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

不知道 gmpy 是否使用它,但如果它确实尝试将普通的 python int 添加到 mpz 与将 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 因为我真的希望它会快很多。

The GMP library itself has a fast short integer add to MPZ routine

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

I don't know whether gmpy uses that, but if it does try adding a normal python int to an mpz vs adding an mpz to mpz and see if it is quicker.

Edit

I tried a bit of benchmarking and found it doesn't make any difference

$ 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

So I guess gmpy doesn't use mpz_add_ui as I really would expect that to be a lot quicker.

一杆小烟枪 2024-08-19 16:52:54

你做了分析吗? Python 和 C++ 的整个应用程序。这样您就知道您确实需要额外的速度。

尝试一下 Python 3k,它现在已经实现了任意长度的整数!

Did you do profiling ? Of Python and C++ whole applications. So that you know that you really need that additional speed.

Try Python 3k it now have any-length integers implemented!

回忆凄美了谁 2024-08-19 16:52:54

(注意:我帮助维护 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 函数与在 long long 上调用本机操作相比会出现 10 倍的性能损失,我不会感到惊讶。

你能将几个小数累积成一个 long long 并将它们一次性添加到你的大数中吗?

(Note: I help maintain GMPY and I've implemented quite a few optimizations in the most recent release.)

GMPY v1.11 does use mpz_add_ui when adding a small number to an mpz. The newest version of GMPY is also about 25% faster than prior versions when working with small numbers.

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

Since it is quicker to convert a Python int to a long and call mpz_add_ui than to convert a Python int to an mpz, there is a moderate performance advantage. I wouldn't be surprised if there is a 10x performance penalty for calling the GMP functions vs. native operations on a long long.

Can you accumulate several of the small numbers into one long long and add them at one time to your large number?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文