sec*_*ind 3 python mapreduce word-count
我试图在python中处理多线程.我有工作代码来计算单词数,带有文本的行数,并创建一个带有每个单词计数的字典.它可以在代码注释中提到的小文件上快速运行.但是我通常使用glob来拉入多个文件.当我这样做时,我的运行时间显着增加.同时,由于我的脚本是单线程的,我看到我有3个其他核心闲置而一个最大化.
我以为我会给pythons多线程模块一个镜头,这是我到目前为止所做的(非工作):
#!/bin/python
#
# test file: http://www.gutenberg.org/ebooks/2852.txt.utf-8
import fileinput
from collections import defaultdict
import threading
import time
inputfilename = 'pg2852.txt'
exitFlag = 0
line = []
line_counter = 0
tot_words = 0
word_dict = defaultdict(int)
def myCounters( threadName, delay):
for line in fileinput.input([inputfilename]):
line = line.strip();
if not line: continue
words = line.split()
tot_words += len(words)
line_counter += 1
for word in words:
word_dict[word] += 1
print "%s: %s:" %( threadName, time.ctime(time.time()) )
print word_dict
print "Total Words: ", tot_words
print "Total Lines: ", line_counter
try:
thread.start_new_thread( myCounters, ("Thread-1", 2, ) )
thread.start_new_thread( myCounters, ("Thread-2", 4, ) )
except:
print "Error: Thread Not Started"
while 1:
pass
Run Code Online (Sandbox Code Playgroud)
对于那些尝试此代码的人来说,它不起作用.我假设我需要将输入文件分成块并以某种方式合并输出.?map/reduce?也许有一个更简单的解决方案?
编辑:
也许是这样的:
首先,你是正确的,你需要使用并行进程而不是并行线程.由于全局解释器锁(GIL),执行此类任务 [请参阅下面的ETA]将无法很好地扩展到python下的多个线程.
如果要并行处理单个文件,显而易见的方法是首先检查文件大小,然后将相等大小的块分配给多个进程.这只会涉及告诉每个进程从文件中的哪个位置开始,以及结束的位置.(当然,你必须要小心不要计算任何单词或行两次.一个简单的方法是让每个进程忽略初始字节,直到它到达行的开头,然后开始计数).
但是,您在问题中声明将使用glob来处理多个文件.因此,不是采用复杂的分块文件路径并将块分配给不同的进程,更简单的选择就是将不同的文件分配给不同的进程.
ETA:
在Python中使用线程适用于某些用例,例如使用阻塞很长时间的I/O函数.@uselpa是正确的,如果处理是I/O绑定,那么线程可能表现良好,但这不是这里的情况,因为瓶颈实际上是解析,而不是文件I/O. 这是由于Python作为解释语言的性能特征; 在编译语言中,I/O更可能成为瓶颈.
我提出这些说法是因为我刚刚根据原始代码进行了一些测量(使用包含100个pg2852.txt连接副本的测试文件):
| 归档时间: |
|
| 查看次数: |
2080 次 |
| 最近记录: |