P
P
Philip Bondarev2017-08-24 16:47:10
Python
Philip Bondarev, 2017-08-24 16:47:10

Incomprehensible slowdown of concatenation in a loop?

All good.
The byte string `buffered_img` is 786'432 bytes long (`Grayscale 8bit` image `1024x768`). The handler thread is launched (If you count in the main thread, then the window just hangs). The algorithm is as follows - the 0th pixel is taken from the original image (the first byte from the string `buffered_img`), its 7th bit is checked, if it is equal to 0, then the byte `'\x00' is appended to the string `nine['img_7']` '`, if 1 then `'\xff'`, then take the 6th bit of the 0th pixel, also check and append to `nine['img_6']` and so on. to bit 0. This operation is repeated for all pixels. As a result, we get 9 images, original + 8 generated.
So, the problem is that with each concatenation operation, the process slows down, the `QProgressBar` slider, which is tied to the `generating` signal, creeps slower and slower with each percentage, although at first everything goes briskly. If the interest had been dripping slowly from the very beginning, there would have been no complaints, but there is a clear slowdown in the concatenation process, and my poor experience in programming is not enough to explain this phenomenon. Who will tell you what the problem is? Here are the pieces of code:

# Глобальный список с байт-строками генерированных картинок
    nine = {'img_7': b'', 'img_6': b'', 'img_5': b'', 'img_4': b'',
        'img_3': b'', 'img_2': b'', 'img_1': b'', 'img_0': b''}
    b0 = pack('B', 0)
    b255 = pack('B', 255)

  # Метод run() QThread в котором buffered_img - байт строка с оригинальным изображением
    def run(self):
        global nine, img_str
        self.start_gen.emit(len(buffered_img))
        pb_val = 0
        for img in nine:
            nine[img] = b''
        for byte_ in buffered_img:
            pb_val += 1
            self.generating.emit(pb_val)
            bit_str = self.by2bi(byte_)
            for i in range(8):
                if bit_str[i] == '0':
                    nine['img_' + str(i)] += b0
                else:
                    nine['img_' + str(i)] += b255
        self.stop_gen.emit()
    
    # Подсмотренный где-то код, на выходе выдает строку типа ('10110100' для
    # входного байта '\xb4'
    def by2bi(self, bytestring):
        try:
            bits = bin(int(hexlify(bytestring), 16))[2:]
            data = bits.zfill(8 * ((len(bits) + 7) // 8))
            del bits
            return data
        except ValueError:
            print 'Error bytes2bits decode!'

Answer the question

In order to leave comments, you need to log in

1 answer(s)
L
longclaps, 2017-08-24
@Dogrtt

Instead of nine[img] = b''declaring nine[img] = bytearray(какой_там_тебе_нужен_размер)and writing to it by index, concatenation slows you down.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question