我需要一种快速的方法来计算 python 中整数的位数.我目前的解决方案是
bin(n).count("1")但我想知道是否有更快的方法来做到这一点?
PS:(我将一个大的二维二进制数组表示为一个数字列表并进行按位运算,这将时间从几小时缩短到几分钟.现在我想摆脱那些额外的分钟.
1. 它必须在 python 2.7 或 2.6 中
优化小数字并不重要,因为这不是一个明显的瓶颈,但我确实在某些地方有 10 000 + 位的数字
例如这是一个 2000 位的情况:
<预> <代码> 12448057941136394342297748548545082997815840357634948550739612798732309975923280685245876950055614362283769710705811182976142803324242407017104841062064840113262840137625582646683068904149296501029754654149991842951570880471230098259905004533869130509989042199261339990315125973721454059973605358766253998615919997174542922163484086066438120268185904663422979603026066685824578356173882166747093246377302371176167843247359636030248569148734824287739046916641832890744168385253915508446422276378715722482359321205673933317512861336054835392844676749610712462818600179225635467147870208L对于任意长度的整数,bin(n).count("1") 是我在纯 Python 中能找到的最快的.
我尝试采用 Óscar 和 Adam 的解决方案分别处理 64 位和 32 位块中的整数.两者都比 bin(n).count("1") 慢了至少十倍(32 位版本又花了大约一半的时间).
另一方面,gmpy popcount()大约是 bin(n).count("1") 时间的 1/20.因此,如果您可以安装 gmpy,请使用它.
要回答评论中的问题,对于字节,我会使用查找表.您可以在运行时生成它:
counts = bytes(bin(x).count("1") for x in range(256)) # py2: 使用 bytearray或者直接定义它:
计数 = (b'x00x01x01x02x01x02x02x03x01x02x02x03x02x03x03x04'b'x01x02x02x03x02x03x03x04x02x03x03x04x03x04x04x05'b'x01x02x02x03x02x03x03x04x02x03x03x04x03x04x04x05'b'x02x03x03x04x03x04x04x05x03x04x04x05x04x05x05x06'b'x01x02x02x03x02x03x03x04x02x03x03x04x03x04x04x05'b'x02x03x03x04x03x04x04x05x03x04x04x05x04x05x05x06'b'x02x03x03x04x03x04x04x05x03x04x04x05x04x05x05x06'b'x03x04x04x05x04x05x05x06x04x05x05x06x05x06x06x07'b'x01x02x02x03x02x03x03x04x02x03x03x04x03x04x04x05'b'x02x03x03x04x03x04x04x05x03x04x04x05x04x05x05x06'b'x02x03x03x04x03x04x04x05x03x04x04x05x04x05x05x06'b'x03x04x04x05x04x05x05x06x04x05x05x06x05x06x06x07'b'x02x03x03x04x03x04x04x05x03x04x04x05x04x05x05x06'b'x03x04x04x05x04x05x05x06x04x05x05x06x05x06x06x07'b'x03x04x04x05x04x05x05x06x04x05x05x06x05x06x06x07'b'x04x05x05x06x05x06x06x07x05x06x06x07x06x07x07x08')然后是 counts[x] 得到 x 中 1 的位数,其中 0 ≤ x ≤ 255.
I need a fast way to count the number of bits in an integer in python. My current solution is
bin(n).count("1")
but I am wondering if there is any faster way of doing this?
PS: (i am representing a big 2D binary array as a single list of numbers and doing bitwise operations, and that brings the time down from hours to minutes. and now I would like to get rid of those extra minutes.
Edit: 1. it has to be in python 2.7 or 2.6
and optimizing for small numbers does not matter that much since that would not be a clear bottleneck, but I do have numbers with 10 000 + bits at some places
for example this is a 2000 bit case:
12448057941136394342297748548545082997815840357634948550739612798732309975923280685245876950055614362283769710705811182976142803324242407017104841062064840113262840137625582646683068904149296501029754654149991842951570880471230098259905004533869130509989042199261339990315125973721454059973605358766253998615919997174542922163484086066438120268185904663422979603026066685824578356173882166747093246377302371176167843247359636030248569148734824287739046916641832890744168385253915508446422276378715722482359321205673933317512861336054835392844676749610712462818600179225635467147870208L
For arbitrary-length integers, bin(n).count("1") is the fastest I could find in pure Python.
I tried adapting Óscar's and Adam's solutions to process the integer in 64-bit and 32-bit chunks, respectively. Both were at least ten times slower than bin(n).count("1") (the 32-bit version took about half again as much time).
On the other hand, gmpy popcount() took about 1/20th of the time of bin(n).count("1"). So if you can install gmpy, use that.
To answer a question in the comments, for bytes I'd use a lookup table. You can generate it at runtime:
counts = bytes(bin(x).count("1") for x in range(256)) # py2: use bytearray
Or just define it literally:
counts = (b'x00x01x01x02x01x02x02x03x01x02x02x03x02x03x03x04'
b'x01x02x02x03x02x03x03x04x02x03x03x04x03x04x04x05'
b'x01x02x02x03x02x03x03x04x02x03x03x04x03x04x04x05'
b'x02x03x03x04x03x04x04x05x03x04x04x05x04x05x05x06'
b'x01x02x02x03x02x03x03x04x02x03x03x04x03x04x04x05'
b'x02x03x03x04x03x04x04x05x03x04x04x05x04x05x05x06'
b'x02x03x03x04x03x04x04x05x03x04x04x05x04x05x05x06'
b'x03x04x04x05x04x05x05x06x04x05x05x06x05x06x06x07'
b'x01x02x02x03x02x03x03x04x02x03x03x04x03x04x04x05'
b'x02x03x03x04x03x04x04x05x03x04x04x05x04x05x05x06'
b'x02x03x03x04x03x04x04x05x03x04x04x05x04x05x05x06'
b'x03x04x04x05x04x05x05x06x04x05x05x06x05x06x06x07'
b'x02x03x03x04x03x04x04x05x03x04x04x05x04x05x05x06'
b'x03x04x04x05x04x05x05x06x04x05x05x06x05x06x06x07'
b'x03x04x04x05x04x05x05x06x04x05x05x06x05x06x06x07'
b'x04x05x05x06x05x06x06x07x05x06x06x07x06x07x07x08')
Then it's counts[x] to get the number of 1 bits in x where 0 ≤ x ≤ 255.
这篇关于以正整数计算非零位的快速方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
如何在python中的感兴趣区域周围绘制一个矩形How to draw a rectangle around a region of interest in python(如何在python中的感兴趣区域周围绘制一个矩形)
如何使用 OpenCV 检测和跟踪人员?How can I detect and track people using OpenCV?(如何使用 OpenCV 检测和跟踪人员?)
如何在图像的多个矩形边界框中应用阈值?How to apply threshold within multiple rectangular bounding boxes in an image?(如何在图像的多个矩形边界框中应用阈值?)
如何下载 Coco Dataset 的特定部分?How can I download a specific part of Coco Dataset?(如何下载 Coco Dataset 的特定部分?)
根据文本方向检测图像方向角度Detect image orientation angle based on text direction(根据文本方向检测图像方向角度)
使用 Opencv 检测图像中矩形的中心和角度Detect centre and angle of rectangles in an image using Opencv(使用 Opencv 检测图像中矩形的中心和角度)