Python 任务包性能低下?
Slow Performance with Python Dask bag?
我正在尝试 dask.bag 的一些测试,以准备对数百万文本文件进行大文本处理作业。现在,在我的数十到数十万个文本文件的测试集中,我发现 dask 运行 比直接的单线程文本处理函数慢大约 5 到 6 倍。
有人可以解释一下 运行 处理大量文本文件的速度优势吗?在它开始变得更快之前我需要处理多少文件? 150,000 个小文本文件是不是太少了?在处理文件时,我应该调整什么样的性能参数来加快速度?与直接单线程文本处理相比,性能下降 5 倍的原因是什么?
这是我用来测试 dask 的代码示例。这是 运行 针对来自路透社的一组测试数据,位于:
http://www.daviddlewis.com/resources/testcollections/reuters21578/
此数据与我处理的数据不完全相同。在我的另一种情况下,它是一堆单独的文本文件,每个文件一个文档,但我看到的性能下降大致相同。这是代码:
import dask.bag as db
from collections import Counter
import string
import glob
import datetime
my_files = "./reuters/*.ascii"
def single_threaded_text_processor():
c = Counter()
for my_file in glob.glob(my_files):
with open(my_file, "r") as f:
d = f.read()
c.update(d.split())
return(c)
start = datetime.datetime.now()
print(single_threaded_text_processor().most_common(5))
print(str(datetime.datetime.now() - start))
start = datetime.datetime.now()
b = db.read_text(my_files)
wordcount = b.str.split().concat().frequencies().topk(5, lambda x: x[1])
print(str([w for w in wordcount]))
print(str(datetime.datetime.now() - start))
这是我的结果:
[('the', 119848), ('of', 72357), ('to', 68642), ('and', 53439), ('in', 49990)]
0:00:02.958721
[(u'the', 119848), (u'of', 72357), (u'to', 68642), (u'and', 53439), (u'in', 49990)]
0:00:17.877077
Dask 对每个任务产生大约 1 毫秒的开销。默认情况下,dask.bag.read_text
函数为每个文件名创建一个任务。我怀疑你只是被头顶淹没了。
这里的解决方案可能是在一个任务中处理多个文件。 read_text 函数没有为您提供任何执行此操作的选项,但您可以切换到 dask.delayed,它提供了更多的灵活性,如果愿意,稍后再转换为 dask.bag。
我正在尝试 dask.bag 的一些测试,以准备对数百万文本文件进行大文本处理作业。现在,在我的数十到数十万个文本文件的测试集中,我发现 dask 运行 比直接的单线程文本处理函数慢大约 5 到 6 倍。
有人可以解释一下 运行 处理大量文本文件的速度优势吗?在它开始变得更快之前我需要处理多少文件? 150,000 个小文本文件是不是太少了?在处理文件时,我应该调整什么样的性能参数来加快速度?与直接单线程文本处理相比,性能下降 5 倍的原因是什么?
这是我用来测试 dask 的代码示例。这是 运行 针对来自路透社的一组测试数据,位于:
http://www.daviddlewis.com/resources/testcollections/reuters21578/
此数据与我处理的数据不完全相同。在我的另一种情况下,它是一堆单独的文本文件,每个文件一个文档,但我看到的性能下降大致相同。这是代码:
import dask.bag as db
from collections import Counter
import string
import glob
import datetime
my_files = "./reuters/*.ascii"
def single_threaded_text_processor():
c = Counter()
for my_file in glob.glob(my_files):
with open(my_file, "r") as f:
d = f.read()
c.update(d.split())
return(c)
start = datetime.datetime.now()
print(single_threaded_text_processor().most_common(5))
print(str(datetime.datetime.now() - start))
start = datetime.datetime.now()
b = db.read_text(my_files)
wordcount = b.str.split().concat().frequencies().topk(5, lambda x: x[1])
print(str([w for w in wordcount]))
print(str(datetime.datetime.now() - start))
这是我的结果:
[('the', 119848), ('of', 72357), ('to', 68642), ('and', 53439), ('in', 49990)]
0:00:02.958721
[(u'the', 119848), (u'of', 72357), (u'to', 68642), (u'and', 53439), (u'in', 49990)]
0:00:17.877077
Dask 对每个任务产生大约 1 毫秒的开销。默认情况下,dask.bag.read_text
函数为每个文件名创建一个任务。我怀疑你只是被头顶淹没了。
这里的解决方案可能是在一个任务中处理多个文件。 read_text 函数没有为您提供任何执行此操作的选项,但您可以切换到 dask.delayed,它提供了更多的灵活性,如果愿意,稍后再转换为 dask.bag。