如何在python中优化一些复杂的二进制算法

时间:2017-11-23 22:09:33

标签: python python-3.x optimization binary bit-manipulation

我正在尝试迭代大量数据并正确组织值。上下文:数据是从原始再见数据解释的一大组整数。整数实际上是密集的数据,最重要的是字节在"小端"订购。因此,为了获得正确的值,我发现我需要读取3个值,提取每个半字节,然后将它们全部重新排序到正确的方向。

所以,最后我的问题。如何加快这一过程或进行优化,因为现在需要一分钟才能完成单个文件中的所有数据,我可能会有数千个文件。

for i in range(0, len(data), 3):
            j = struct.pack("=I", data[i])
            p = struct.pack("=I", data[i + 1])
            q = struct.pack("=I", data[i + 2])
            nibble0 = j[1] >> 4
            nibble1 = j[1] & 15
            nibble2 = j[0] >> 4
            nibble3 = j[0] & 15
            nibble4 = j[3] >> 4
            nibble5 = j[3] & 15
            nibble6 = j[2] >> 4
            nibble7 = j[2] & 15
            nibble8 = p[1] >> 4
            nibble9 = p[1] & 15
            nibble10 = p[0] >> 4
            nibble11 = p[0] & 15
            nibble12 = p[3] >> 4
            nibble13 = p[3] & 15
            nibble14 = p[2] >> 4
            nibble15 = p[2] & 15
            nibble16 = q[1] >> 4
            nibble17 = q[1] & 15
            nibble18 = q[0] >> 4
            nibble19 = q[0] & 15
            nibble20 = q[3] >> 4
            nibble21 = q[3] & 15
            nibble22 = q[2] >> 4
            nibble23 = q[2] & 15

k.append((nibble0 << 12) | (nibble1 << 8) | (nibble2 << 4) | 0)

k.append((nibble3 << 12) | (nibble4 << 8) | (nibble5 << 4) | 0)

k.append((nibble6 << 12) | (nibble7 << 8) | (nibble8 << 4) | 0)

k.append((nibble9 << 12) | (nibble10 << 8) | (nibble11 << 4) | 0)

k.append((nibble12 << 12) | (nibble13 << 8) | (nibble14 << 4) | 0)

k.append((nibble15 << 12) | (nibble16 << 8) | (nibble17 << 4) | 0)

k.append((nibble18 << 12) | (nibble19 << 8) | (nibble20 << 4) | 0)

k.append((nibble21 << 12) | (nibble22 << 8) | (nibble23 << 4) | 0)

我希望在不使用Anaconda或Pypy或任何预先构建的python包的情况下执行此操作。

1 个答案:

答案 0 :(得分:0)

请注意,您只需要将半字节用于调试目的,并且可以排除某些操作:

        nibble0 = j[1] >> 4
        nibble1 = j[1] & 15
        nibble2 = j[0] >> 4
        k.append((nibble0 << 12) | (nibble1 << 8) | (nibble2 << 4) | 0)

    is equivalent to 

        k.append((j[1] << 8) | (j[0] % F0))

   and 
       nibble3 = j[0] & 15
       nibble4 = j[3] >> 4
       nibble5 = j[3] & 15
       k.append((nibble3 << 12) | (nibble4 << 8) | (nibble5 << 4) | 0)   

  is equivalent to 

       k.append((j[0] << 12) | (j[3] << 4))

  (if k gets 16-bit values, otherwise clear MSB bits of j[0])