2009-12-02 35 views
5

Tôi đã sử dụng bignums gốc của python cho một thuật toán và quyết định thử và tăng tốc nó bằng cách chuyển đổi nó thành C++. Khi tôi sử dụng longs dài, C + + là khoảng 100x nhanh hơn so với python, nhưng khi tôi sử dụng bindings GMP trong C + +, nó chỉ là 10x nhanh hơn so với python (cho các trường hợp tương tự phù hợp với longs dài).Thực hiện Bignum có bổ sung hiệu quả các số nguyên nhỏ

Có triển khai bignum tốt hơn để thực hiện một số lượng lớn các bổ sung nhỏ không? Ví dụ, chúng tôi có một số lượng lớn N chúng tôi sẽ bổ sung thêm rất nhiều +1, +21, +1, v.v ... và mỗi lần một lần và thêm một số lượng lớn M?

Trả lời

2

Các GMP thư viện chính nó có một fast short integer add to MPZ routine

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

Tôi không biết liệu gmpy sử dụng đó, nhưng nếu nó không thử thêm một con trăn int bình thường để một MPZ vs thêm một MPZ để MPZ và xem nếu nó nhanh hơn.

Sửa

Tôi đã thử một chút điểm chuẩn và thấy nó không thực hiện bất kỳ sự khác biệt

$ 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 

Vì vậy, tôi đoán gmpy không sử dụng mpz_add_ui như tôi thực sự hy vọng rằng là nhanh hơn rất nhiều.

+0

Thú vị. Tôi đang sử dụng quá tải C++ của các phép tính số học, có lẽ các ràng buộc C++ này cũng không sử dụng phương thức nhanh này. Tôi sẽ làm một số xét nghiệm vào ngày mai. Cảm ơn! – sligocki

0

Bạn đã định hình chưa? Của Python và C++ toàn bộ các ứng dụng. Vì vậy, bạn biết rằng bạn thực sự cần tốc độ bổ sung đó.

Hãy thử Python 3k bây giờ nó có số nguyên bất kỳ chiều dài được triển khai!

+0

Sự suy giảm này là cho toàn bộ chương trình khi thay đổi duy nhất là từ lâu dài đến GMP MPZ. Cảm ơn. – sligocki

+1

Ý của bạn là gì bởi "Python 3k bây giờ có số nguyên bất kỳ chiều dài"? Python đã có số nguyên dài tùy ý vì ít nhất là phiên bản 2.5 (và có lẽ cách trước). – EOL

+0

Bây giờ tất cả ints tất cả các chiều dài bất kỳ –

0

(Lưu ý:. Tôi giúp duy trì GMPY và tôi đã thực hiện một vài tối ưu hóa trong việc phát hành gần đây nhất)

GMPY v1.11 không sử dụng mpz_add_ui khi thêm một số nhỏ đến một MPZ. Phiên bản mới nhất của GMPY cũng nhanh hơn khoảng 25% so với các phiên bản trước khi làm việc với số lượng nhỏ.

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 

Vì nó là nhanh hơn để chuyển đổi một int Python để lâu và gọi mpz_add_ui hơn để chuyển đổi một int Python để một MPZ, có một lợi thế hiệu suất vừa phải. Tôi sẽ không ngạc nhiên nếu có một hình phạt hiệu suất 10x để gọi các chức năng GMP so với các hoạt động bản địa trên một thời gian dài.

Bạn có thể tích lũy một số số nhỏ thành một số dài và thêm chúng cùng một lúc vào số lớn của bạn không?

+0

Vâng, tôi đã xem xét việc viết lớp của riêng mình để tích lũy các số nhỏ và thêm chúng vào một số lượng lớn không thường xuyên. Cảm ơn ghi chú về GMPY 1.11. – sligocki

Các vấn đề liên quan