Уведомления

Группа в Telegram: @pythonsu

#1 Май 28, 2012 22:11:53

asilyator
От:
Зарегистрирован: 2010-10-24
Сообщения: 276
Репутация: +  -2  -
Профиль   Отправить e-mail  

Ускорить функцию

Есть одна функция, суть такова: переворачивать байты в дверде, т.е. “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 сливаются.



Отредактировано asilyator (Май 28, 2012 22:12:40)

Офлайн

#2 Май 28, 2012 22:38:57

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Ускорить функцию

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 сливаются.
Почитайте Макконнелла.



Отредактировано fata1ex (Май 28, 2012 22:42:40)

Офлайн

#3 Май 28, 2012 22:48:36

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Ускорить функцию

По-моему, вы делаете что-то не так. Если это бинарные данные, то читать их лучше сразу в 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 тоже убрать)

Отредактировано reclosedev (Май 28, 2012 22:51:56)

Офлайн

#4 Май 28, 2012 22:54:16

asilyator
От:
Зарегистрирован: 2010-10-24
Сообщения: 276
Репутация: +  -2  -
Профиль   Отправить e-mail  

Ускорить функцию

Питонотсос. Расшифровать нативным модулем быстрее, чем перевернуть дверды.

Мой вариант:

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-ом прочитаю, второй раз придется руками, да и не факт, что это сильно ускорит - скорость ниже нужной больше, чем на порядок.



Отредактировано asilyator (Май 28, 2012 23:01:28)

Офлайн

#5 Май 28, 2012 23:01:25

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Ускорить функцию

Хм. Результаты по времени с последним вариантом идентичные. Интересно было бы посмотреть на ассемблерный код.

Питонотсос.
Как ни банально, но для каждой задачи - свой инструмент. Нужна скорость обработки простых данных, выбирайте Си, а не питон. Ну а если всё-таки питон, то вставить в код сишную функцию довольно просто.



Отредактировано fata1ex (Май 28, 2012 23:03:24)

Офлайн

#6 Май 28, 2012 23:02:48

asilyator
От:
Зарегистрирован: 2010-10-24
Сообщения: 276
Репутация: +  -2  -
Профиль   Отправить e-mail  

Ускорить функцию

Меня все устраивает, кроме этого самого места. Что прикажете делать? Писать расширение на си или из-за одного места менять язык?



Офлайн

#7 Май 28, 2012 23:03:41

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Ускорить функцию

Однозначно делать вставку на Си.



Офлайн

#8 Май 28, 2012 23:04:51

asilyator
От:
Зарегистрирован: 2010-10-24
Сообщения: 276
Репутация: +  -2  -
Профиль   Отправить e-mail  

Ускорить функцию

И как это потом распространять прикажете?



Офлайн

#9 Май 28, 2012 23:06:40

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Ускорить функцию

asilyator
reverse(decrypt(reverse))
А что происходит в decrypt? Есть возможность скинуть код?

Офлайн

#10 Май 28, 2012 23:07:15

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Ускорить функцию

Через build-скрипт setup.py как обычно. clck



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version