Search code examples
pythonperformancedata-processingbitarraybitstring

Python efficient assigning of even and odd bits to a bitstring/bit_array


I receive serialized DDR data from a setup with 8 chips. Due to the way the readout is implemented in hardware, the data that is received by the computer has the following structure:

bits 0 and 1 of Chip A, bits 0 and 1 of Chip B, ... bits 2 and 3 of Chip A, bits 2 and 3 of Chip B, ...

In order to make sense of the individual reply of each chip, the data needs to be split:

import bitstring

data = bitstring.BitArray(1024)  # contains serialized DDR data of 8 chips (here just 0 values for demo purposes)

even_bits_of_chip_A = data[0::16]  # starting at position 0, every 16th bit is an even bit of chip A
odd_bits_of_chip_A = data[1::16]  # starting at position 1, every 16th bit is an odd bit of chip A

data_of_chip_A = bitstring.BitArray(len(even_bits_of_chip_A) + len(odd_bits_of_chip_A))
data_of_chip_A[0::2] = even_bits_of_chip_A
data_of_chip_A[1::2] = odd_bits_of_chip_A

This code works fine and does what I want it to do. However, it is not that fast (considering I have to do this for all 8 chips, and generally with a lot more than 1024 bits). Is there a way to speed it up?

Of course the code can be rewritten like this:

import bitstring

data = bitstring.BitArray(1024)

data_of_chip_A = bitstring.BitArray(int(len(data) / 8))
data_of_chip_A[0::2] = data[0::16]
data_of_chip_A[1::2] = data[1::16]

This avoids the creation of the even_bits, odd_bits variables and increases performance. But the final step of assigning values to every second bit of data_of_chip_A still takes quite some time. Is there a way to for example join two bit_arrays in "alternating" fashion?


Solution

  • As suggested in one of the comments, I switched to bitarray. It works fairly similar to bitstring and is way faster. Together with some simple multiprocessing the script runs 24x faster now. Thanks for the suggestions!

    from bitarray import bitarray
    
    data = bitarray(1024)  # empty/random array with 1024 bits
    even_bits_of_chip_A = data[0::16]  # starting at position 0, every 16th bit is an even bit of chip A
    odd_bits_of_chip_A = data[1::16]  # starting at position 1, every 16th bit is an odd bit of chip A
    
    data_of_chip_A = bitarray(len(even_bits_of_chip_A) + len(odd_bits_of_chip_A))
    data_of_chip_A[0::2] = even_bits_of_chip_A
    data_of_chip_A[1::2] = odd_bits_of_chip_A