好吧,所以这个文件是410k行代码。现在我在1.4秒内解析它,但我需要它更快。虽然这个文件有几个奇怪的东西......
该文件的结构类似于此(感谢ARM):ARM fromelf
基本上我将所有这些解析为一个映射,其中键是结构的名称,在这种情况下,由于ARM生成警告,可以复制。这种情况下的值是后面的字段。
有没有办法可以使用线程将任务拆分为多个线程,将数据添加到同一个地图中?
P.S。我没有找人为我这样做,我只提供了一个文件结构是什么样的例子,所以你理解我不能只处理每一行,而是根据结构从[start:finish]开始处理。 / p>
每个请求,我正在解析的一个示例:
; Structure, Table , Size 0x104 bytes, from inputfile.cpp
|Table.TableSize| EQU 0 ; int
|Table.Data| EQU 0x4 ; array[64] of MyClassHandle
; End of Structure Table
; Structure, Box2 , Size 0x8 bytes, from inputfile.cpp
|Box2.| EQU 0 ; anonymous
|Box2..| EQU 0 ; anonymous
|Box2...Min| EQU 0 ; Point2
|Box2...Min.x| EQU 0 ; short
|Box2...Min.y| EQU 0x2 ; short
|Box2...Max| EQU 0x4 ; Point2
|Box2...Max.x| EQU 0x4 ; short
|Box2...Max.y| EQU 0x6 ; short
; Warning: duplicate name (Box2..) present in (inputfile.cpp) and in (inputfile.cpp)
; please use the --qualify option
|Box2..| EQU 0 ; anonymous
|Box2...Left| EQU 0 ; unsigned short
|Box2...Top| EQU 0x2 ; unsigned short
|Box2...Right| EQU 0x4 ; unsigned short
|Box2...Bottom| EQU 0x6 ; unsigned short
; End of Structure Box2
; Structure, MyClassHandle , Size 0x4 bytes, from inputfile.cpp
|MyClassHandle.Handle| EQU 0 ; pointer to MyClass
; End of Structure MyClassHandle
; Structure, Point2 , Size 0x4 bytes, from defects.cpp
|Point2.x| EQU 0 ; short
|Point2.y| EQU 0x2 ; short
; End of Structure Point2
; Structure, __fpos_t_struct , Size 0x10 bytes, from C:\Program Files\DS-5\bin\..\include\stdio.h
|__fpos_t_struct.__pos| EQU 0 ; unsigned long long
|__fpos_t_struct.__mbstate| EQU 0x8 ; anonymous
|__fpos_t_struct.__mbstate.__state1| EQU 0x8 ; unsigned int
|__fpos_t_struct.__mbstate.__state2| EQU 0xc ; unsigned int
; End of Structure __fpos_t_struct
END
答案 0 :(得分:0)
最好优化解析器代码,或用其他语言编写代码。
在标准Python实现(“CPython”)中,有效多进程的唯一方法是使用multiprocessing模块,该模块依赖于使用多个unix进程而不是线程(线程实际上不可能进行线程化)由于全局解释器锁定的绑定任务)。您可以使用共享内存对象甚至共享字典(请参阅Managers),但基本上进程间通信非常昂贵,并且很快就会消耗多任务处理的优势。
如果您的个别线程在解析期间不需要有关结构的全局信息,则每个线程都可以创建自己的字典,然后您可以在最后合并所有字典。将(可选择的)Python对象从一个进程发送到另一个进程很容易,但请考虑以下内容:您的任务是解析文本表示并创建内部表示。对对象进行pickle和unpickling包括获取内部表示,从中生成字符串,然后在通信通道的另一端解析字符串。换句话说,您的解析任务只是生成另一个解析任务,还有一些额外的序列化开销。这不太可能是一个胜利,除了unpickler可能是一个比你写的更快的解析器。这让我们回到优化解析器。
并行化问题的一部分通常是直接的,即在进程之间拆分任务。假设要解析的块(start:finish
)不是太大 - 也就是说,你的410k行包含数千个这样的子任务 - 那么就有一个简单的策略:
[task_number * task_size, task_number * task_size)
。这个简单算法的问题在于它假设解析的成本与解析的字符数严格成比例,并且所有线程将以相同的速度执行。由于这些假设都不可能,因此很有可能某些线程会先于其他线程完成,然后只需旋转轮子等待更多工作。
这可以通过将文件拆分成更小的部分并让每个线程在完成正在处理的文件时获得下一个可用的部分来避免。 (当然,你必须协调工作队列,但每个工作块只有一个同步,这不是很多开销。)但是,我没有推荐这个,因为输入文件不是那么大,以至于它可以分成很小的一块。由于需要在实际扫描中找到实际的工作开始和结束,因此与每个工作块相关的一些开销并且存在的块越多,开销就越大。如果块足够小,将会有一些根本没有实际工作。正确地获得调整参数需要更多关于工作单元大小的知识,而不是问题所揭示的。