Эффективная строка в шестнадцатеричную функцию - PullRequest
3 голосов
/ 30 октября 2011

Я использую старую версию python на встроенной платформе ( Python 1.5.2+ на платформе Telit ). Проблема в том, что у меня есть функция преобразования строки в шестнадцатеричное. Это очень медленно. Вот функция:

def StringToHexString(s):
    strHex=''

    for c in s:
        strHex = strHex + hexLoookup[ord(c)]

    return strHex

hexLookup - это справочная таблица (список python), содержащая все шестнадцатеричные представления каждого символа.

Я готов попробовать все (более компактная функция, некоторые языковые трюки, о которых я не знаю). Чтобы быть более понятным, вот тесты (разрешение на этой платформе составляет 1 секунду):

N - количество вводимых символов, которые необходимо преобразовать в шестнадцатеричное, а время указывается в секундах.

  • N | Время (секунды)
  • 50 | 1
  • 150 | 3
  • 300 | 4 * * тысяча двадцать-один
  • 500 | 8
  • 1000 | 15
  • 1500 | 23
  • 2000 | 31

Да, я знаю, это очень медленно ... но если бы я мог получить что-то вроде 1 или 2 секунд, это был бы прогресс.

Так что любое решение приветствуется, особенно от людей, которые знают о производительности Python.

Спасибо

Юлиан

PS1: (после тестирования предложенных предложений - сохранение вызова ord):

def StringToHexString(s):
    hexList=[]
    hexListAppend=hexList.append

    for c in s:
        hexListAppend(hexLoookup[ord(c)])

    return ''.join(hexList)

С помощью этой функции я получил следующие значения: 1/2/3/5/12/19/27 (что явно лучше)

PS2 (не могу объяснить, но это невероятно быстро) БОЛЬШОЕ спасибо Свену Марнаху за идею !!!:

def StringToHexString(s):
    return ''.join( map(lambda param:hexLoookup[param], map(ord,s) ) )
* * Времена одна тысячи сорок-девять: 1/1/2/3/6/10/12

Любые другие идеи / объяснения приветствуются!

Ответы [ 5 ]

5 голосов
/ 30 октября 2011

Сделайте ваш hexLoookup словарем, индексированным самими символами, чтобы вам не приходилось каждый раз вызывать ord.

Кроме того, не объединяйте строки, которые раньше создавались медленно.Вместо этого используйте join в списке.

from string import join
def StringToHexString(s):
    strHex = []

    for c in s:
        strHex.append(hexLoookup[c])

    return join(strHex, '')
2 голосов
/ 30 октября 2011

Опираясь на Ответ Петра Викторина , вы можете еще больше повысить производительность, избегая поиска глобальных переменных и атрибутов в пользу поиска локальных переменных. Локальные переменные оптимизированы, чтобы избежать поиска в словаре при каждом доступе. (Они не всегда были, я просто дважды проверил, что эта оптимизация уже была в 1.5.2, выпущенной в 1999 году.)

from string import join
def StringToHexString(s):
    strHex = []
    strHexappend = strHex.append
    _hexLookup = hexLoookup
    for c in s:
        strHexappend(_hexLoookup[c])
    return join(strHex, '')
1 голос
/ 30 октября 2011

Попробуйте:

from string import join

def StringToHexString(s):
    charlist = []

    for c in s:
        charlist.append(hexLoookup[ord(c)])

    return join(charlist, '')

Каждое добавление строки занимает время, пропорциональное длине строки, поэтому, join также займет время, пропорциональное длине всей строки, но высделать это нужно только один раз .

. Вы также можете сделать hexLookup a dict, отображая символы в шестнадцатеричные значения, поэтому вам не нужно вызывать ord для каждого символа.Это микрооптимизация, поэтому, вероятно, не будет значительным.

1 голос
/ 30 октября 2011

Постоянное переназначение и добавление строк с помощью оператора + выполняется очень медленно.Я думаю, что Python 1.5.2 еще не оптимизирован для этого.Поэтому было бы предпочтительнее использовать string.join().

Попробуйте

import string
def StringToHexString(s):
    listhex = []
    for c in s:
        listhex.append(hexLookup[ord(c)])
    return string.join(listhex, '')

и посмотрите, быстрее ли это.

0 голосов
/ 31 октября 2011
def StringToHexString(s):
    return ''.join( map(lambda param:hexLoookup[param], map(ord,s) ) )

Похоже, это самый быстрый! Спасибо Свен Марнах!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...