"加快Python的struct.unp"

2024-10-05 14:22:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在努力加快我的剧本速度。它基本上读取一个pcap文件,其中包含Velodyne的lidarhdl-32信息,并允许我获得X、Y、Z和强度值。我使用python -m cProfile ./spTestPcapToLas.py分析了我的脚本,它在我的readDataPacket()函数调用中花费的时间最多。在一个小测试(80MB文件)中,解包部分占用大约56%的执行时间。在

我像这样调用readDataPacket函数(chunk引用pcap文件):

packets = []
for packet in chunk:
    memoryView = memoryview(packet.raw())
    udpDestinationPort = unpack('!h', memoryView[36:38].tobytes())[0]

    if udpDestinationPort == 2368:
        packets += readDataPacket(memoryView)

readDataPacket()函数本身的定义如下:

^{pr2}$

有什么想法可以加快这个过程吗?顺便说一下,我用numpy计算X,Y,Z,强度。在


Tags: 文件函数packet时间pcap速度packets剧本
3条回答

Numpy让你可以很快做到这一点。在这种情况下,我认为最简单的方法是直接使用^{}构造函数:

import numpy as np

def with_numpy(buffer):
    # Construct ndarray with: shape, dtype, buffer, offset, strides.
    rotational = np.ndarray((firingBlocks,), '<H', buffer, 42+2, (100,))
    distance = np.ndarray((firingBlocks,lasers), '<H', buffer, 42+4, (100,3))
    intensity = np.ndarray((firingBlocks,lasers), '<B', buffer, 42+6, (100,3))
    return rotational, distance*0.002, intensity

这将返回单独的数组而不是嵌套的列表,这应该更容易进一步处理。作为输入,它接受一个buffer对象(在python2中)或任何公开缓冲区接口的对象。不幸的是,这取决于您的Python版本(2/3),您可以确切地使用哪些对象。但这种方法非常快速:

^{pr2}$

您可以在一个调用中将原始distanceInformationintensity值一起解包。尤其是因为您只是将它们放在一个列表中:当unpack()解包多个值时,它就是这样做的。在您的例子中,您需要将distanceInformation乘以0.002,但是您可以将其留待以后来节省时间,因为您可以使用^{}在一个调用中解析整个原始对列表。该函数为您提供了一个生成器,它可以用^{}切片,然后转换成一个列表。像这样:

laser_iter = struct.iter_unpack('<HB', firingData[firingDataStartingByte + 4])
laser = [[d * 0.002, i] for d, i in itertools.islice(laser_iter, lasers)]

不幸的是,这有点难以阅读,所以您可能需要找到一种方法,将其扩展到更多的代码行中,使用更具描述性的变量名,或者在您忘记编写此代码的原因时添加注释

提前编译Struct,以避免使用模块级方法的Python级包装代码。在环路外进行,这样就不会重复支付施工成本。在

unpack_ushort = struct.Struct('<H').unpack
unpack_ushort_byte = struct.Struct('<HB').unpack

Struct方法本身是用C语言在CPython中实现的(模块级方法在解析格式字符串后最终委托给相同的工作),因此只构建一次Struct并存储绑定方法可以节省大量的工作,尤其是在解压少量值时。在

也可以通过将多个值(而不是一次一个)解压来节省一些工作:

^{pr2}$

作为Dan notes,您可以使用iter_unpack进一步改进这一点,这将进一步减少字节码执行和小片段操作的数量。在

相关问题 更多 >