Effizienter Weg, um konvertieren von string zu ctypes.c_ubyte array in Python

Ich habe einen string, 20 bytes, und ich möchte es zu konvertieren, eine ctypes.c_ubyte array für Bitfeld-manipulation Zwecke.

 import ctypes
 str_bytes = '01234567890123456789'
 byte_arr = bytearray(str_bytes)
 raw_bytes = (ctypes.c_ubyte*20)(*(byte_arr))

Gibt es eine Möglichkeit zu vermeiden, eine Tiefe Kopie von str auf bytearray-zum Wohle der Besetzung?

Alternativ ist es möglich, zu konvertieren einen string in ein bytearray ohne eine Tiefe Kopie? (Mit Techniken wie memoryview?)

Ich verwende Python 2.7.

Performance-Ergebnisse:

Mit eryksun und Brian Larsen's Vorschlag, hier sind die benchmarks unter einer vbox-VM mit Ubuntu 12.04 und Python 2.7.

  • methode1 nutzt mein original-Beitrag
  • methode2 verwendet ctype from_buffer_copy
  • Methode3 verwendet ctype cast/ZEIGER
  • method4 verwendet numpy

Ergebnisse:

  • methode1 nimmt 3.87 sec
  • methode2 nimmt 0.42 sec
  • Methode3 nimmt 1.44 sec
  • method4 nimmt 8.79 Sek.

Code:

import ctypes
import time
import numpy

str_bytes = '01234567890123456789'

def method1():
    result = ''
    t0 = time.clock()
    for x in xrange(0,1000000):     
        byte_arr = bytearray(str_bytes)
        result = (ctypes.c_ubyte*20)(*(byte_arr))

    t1 = time.clock()
    print(t1-t0)

    return result

def method2():

    result = ''
    t0 = time.clock()
    for x in xrange(0,1000000):     
        result = (ctypes.c_ubyte * 20).from_buffer_copy(str_bytes)

    t1 = time.clock()
    print(t1-t0)

    return result

def method3():

    result = ''
    t0 = time.clock()
    for x in xrange(0,1000000):     
        result = ctypes.cast(str_bytes, ctypes.POINTER(ctypes.c_ubyte * 20))[0]

    t1 = time.clock()
    print(t1-t0)

    return result

def method4():

    result = ''
    t0 = time.clock()
    for x in xrange(0,1000000):     
        arr = numpy.asarray(str_bytes)
        result = arr.ctypes.data_as(ctypes.POINTER(ctypes.c_ubyte*len(str_bytes)))

    t1 = time.clock()
    print(t1-t0)

    return result

print(method1())
print(method2())
print(method3())
print(method4())
  • Für 20 bytes, bezweifle ich, es gibt viel zu optimieren.
  • Python-strings sind unveränderlich, so dass Sie nur zu tun haben mit den Kosten der Tiefe Kopie, wenn Sie Sie verändern wollen.
  • Leider habe ich dazu paar tausend mal in der Sekunde. Dies ist immer ein hotspot für meinen code.
InformationsquelleAutor askldjd | 2014-01-31
Schreibe einen Kommentar