高效的字符串到十六进制功能

时间:2011-10-30 08:19:19

标签: python hex

我在嵌入式平台(Python 1.5.2+ on Telit platform)上使用旧版本的python。我遇到的问题是我将字符串转换为十六进制的函数。这很慢。这是功能:

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(无法解释,但速度非常快)非常感谢Sven Marnach的想法!:

def StringToHexString(s):
    return ''.join( map(lambda param:hexLoookup[param], map(ord,s) ) )

时间:1/1/2/3/6/10/12

欢迎任何其他想法/解释!

5 个答案:

答案 0 :(得分:5)

使你的hexLoookup成为一个由字符本身编入索引的字典,这样你就不必每次都调用ord

另外,不要连接到构建字符串 - 过去很慢。而是在列表中使用join

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

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

    return join(strHex, '')

答案 1 :(得分:2)

Petr Viktorin's answer的基础上,您可以通过避免全局可修改和属性查找来支持本地变量查找,从而进一步提高性能。优化局部变量以避免在每次访问时查找字典。 (他们并非总是如此,我只是仔细检查过这种优化已经在1999年发布的1.5.2中实现了。)

from string import join
def StringToHexString(s):
    strHex = []
    strHexappend = strHex.append
    _hexLookup = hexLoookup
    for c in s:
        strHexappend(_hexLoookup[c])
    return join(strHex, '')

答案 2 :(得分:1)

使用+运算符不断重新分配和添加字符串非常慢。我想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, '')

并查看是否更快。

答案 3 :(得分:1)

尝试:

from string import join

def StringToHexString(s):
    charlist = []

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

    return join(charlist, '')

每个字符串的添加需要时间与字符串的长度成比例,所以join也需要时间与整个字符串的长度成比例,但是你只需要做一次

您还可以将hexLookupdict映射字符设置为十六进制值,这样您就不必为每个字符调用ord。这是一个微观优化,所以可能不会很重要。

答案 4 :(得分:0)

def StringToHexString(s):
    return ''.join( map(lambda param:hexLoookup[param], map(ord,s) ) )
似乎这是最快的!谢谢Sven Marnach!