Найти - Пользователи
Полная версия: Ускорить функцию
Начало » Python для новичков » Ускорить функцию
1 2 3
asilyator
Есть одна функция, суть такова: переворачивать байты в дверде, т.е. “12345678” должно стать “43218765”. То, что я написал, по сравнению со скоростью чтения диска безбожно тормозит. Ваши предложения?

def reverseDwords(data):
    assert len(data) % 4 == 0, "Data length must be multiple of 4 but is %s" % len(data)
    l = []
    i = iter(data)
    for x in range(len(data) // 4):
        l1 = [i.next(), i.next(), i.next(), i.next()]
        l1.reverse() 
        l += l1
    return "".join(l)

З.Ы. Ой как хорошо у вас 1 и l сливаются.
fata1ex
def foo(s):
        # assert ...
	result = ''
	for step in xrange(len(s)/4):
		result = ''.join((result, s[4*step:4*(step+1)][::-1]))
	return result
Примерно в два раза быстрее.

З.Ы. Ой как хорошо у вас 1 и l сливаются.
Почитайте Макконнелла.
reclosedev
По-моему, вы делаете что-то не так. Если это бинарные данные, то читать их лучше сразу в unsigned int с соответствующим порядком байт (Little или Big endian) с помощью модуля struct.

Но если все-таки нужна функция, можно и со struct сделать:
def reverse_with_struct(data):
    assert len(data) % 4 == 0, "Data length must be multiple of 4 but is %s" % len(data)
    ndwords = len(data)//4
    return struct.pack(">%dI" % ndwords, *struct.unpack("<%dI" % ndwords, data))
Чуть быстрей чем у fata1ex (если assert тоже убрать)
asilyator
Питонотсос. Расшифровать нативным модулем быстрее, чем перевернуть дверды.

Мой вариант:
def reverse(data):
    assert len(data) % 4 == 0, "Data length must be multiple of 4 but is %s" % len(data)
    b = bytearray(data)
    for x in xrange(0, len(data), 4):
        b[0+x], b[1+x], b[2+x], b[3+x] = b[3+x], b[2+x], b[1+x], b[0+x]
    return b
В 2 раза быстрее, но все равно это 3,5 секунды на 10 метров, когда винт у меня читает под 50 в секунду.

reclosedev, я все делаю так. Код выглядит так:

reverse(decrypt(reverse))
Даже если я struct-ом прочитаю, второй раз придется руками, да и не факт, что это сильно ускорит - скорость ниже нужной больше, чем на порядок.
fata1ex
Хм. Результаты по времени с последним вариантом идентичные. Интересно было бы посмотреть на ассемблерный код.

Питонотсос.
Как ни банально, но для каждой задачи - свой инструмент. Нужна скорость обработки простых данных, выбирайте Си, а не питон. Ну а если всё-таки питон, то вставить в код сишную функцию довольно просто.
asilyator
Меня все устраивает, кроме этого самого места. Что прикажете делать? Писать расширение на си или из-за одного места менять язык?
fata1ex
Однозначно делать вставку на Си.
asilyator
И как это потом распространять прикажете?
reclosedev
asilyator
reverse(decrypt(reverse))
А что происходит в decrypt? Есть возможность скинуть код?
fata1ex
Через build-скрипт setup.py как обычно. clck
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB