Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient string to hex function

Tags:

python

hex

I'm using an old version of python on an embedded platform ( Python 1.5.2+ on Telit platform ). The problem that I have is my function for converting a string to hex. It is very slow. Here is the function:

def StringToHexString(s):
    strHex=''

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

    return strHex

hexLookup is a lookup table (a python list) containing all the hex representation of each character.

I am willing to try everything (a more compact function, some language tricks I don't know about). To be more clear here are the benchmarks (resolution is 1 second on that platform):

N is the number of input characters to be converted to hex and the time is in seconds.

  • N | Time (seconds)
  • 50 | 1
  • 150 | 3
  • 300 | 4
  • 500 | 8
  • 1000 | 15
  • 1500 | 23
  • 2000 | 31

Yes, I know, it is very slow... but if I could gain something like 1 or 2 seconds it would be a progress.

So any solution is welcomed, especially from people who know about python performance.

Thanks,

Iulian

PS1: (after testing the suggestions offered - keeping the ord call):

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

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

    return ''.join(hexList)

With this function I obtained the following times: 1/2/3/5/12/19/27 (which is clearly better)

PS2 (can't explain but it's blazingly fast) A BIG thank you Sven Marnach for the idea !!!:

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

Times:1/1/2/3/6/10/12

Any other ideas/explanations are welcome!

like image 709
INS Avatar asked Dec 21 '25 05:12

INS


2 Answers

Make your hexLoookup a dictionary indexed by the characters themselves, so you don't have to call ord each time.

Also, don't concatenate to build strings – that used to be slow. Use join on a list instead.

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

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

    return join(strHex, '')
like image 115
Petr Viktorin Avatar answered Dec 22 '25 18:12

Petr Viktorin


Building on Petr Viktorin's answer, you could further improve the performance by avoiding global vairable and attribute look-ups in favour of local variable look-ups. Local variables are optimized to avoid a dictionary look-up on each access. (They haven't always been, by I just double-checked this optimization was already in place in 1.5.2, released in 1999.)

from string import join
def StringToHexString(s):
    strHex = []
    strHexappend = strHex.append
    _hexLookup = hexLoookup
    for c in s:
        strHexappend(_hexLoookup[c])
    return join(strHex, '')
like image 44
Sven Marnach Avatar answered Dec 22 '25 19:12

Sven Marnach



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!