【问题标题】:Parallel writes to xlsxwriter worksheet slower than sequential writes并行写入 xlsxwriter 工作表比顺序写入慢
【发布时间】:2018-02-23 04:59:04
【问题描述】:

我想同时写入同一工作簿的多个工作表。 代码如下:

import threading
import xlsxwriter
import time


def write_to_w1(w1, data):
    print('task1 executing....')
    for row, item in enumerate(data):
        w1.write(row, 0, item, row_format)

def write_to_w2(w2, data):
    print('task2 executing....')
    for row, item in enumerate(data):
        w2.write(row, 0, item, row_format)

def write_to_w3(w3, data):
    print('task3 executing....')
    for row, item in enumerate(data):
        w3.write(row, 0, item, row_format)


start = time.time()
data1 = [i for i in range(0,500000)]
data2 = [i for i in range(0,500000)]
data3 = [i for i in range(0,500000)]

workbook = xlsxwriter.Workbook('~/Desktop/threading.xlsx')
row_format = workbook.add_format({'bold': False, 'align': 'left', 'text_wrap': True, 'valign': 'vcenter'})
w1 = workbook.add_worksheet('w1')
w2 = workbook.add_worksheet('w2')
w3 = workbook.add_worksheet('w3')

t1 = threading.Thread(target=write_to_w1, args=(w1, data1), name='t1')
t2 = threading.Thread(target=write_to_w2, args=(w2, data2), name='t2')
t3 = threading.Thread(target=write_to_w3, args=(w3, data3), name='t3')

# starting thread 1
t1.start()
# starting thread 2
t2.start()
# starting thread 3
t3.start()

# wait until thread 1 is completely executed
t1.join()
# wait until thread 2 is completely executed
t2.join()
# wait until thread 3 is completely executed
t3.join()

# both threads completely executed
print("Done!")
workbook.close()
end = time.time()
print('total time ==>', end-start)

在使用顺序执行进行基准测试时,并行版本大约需要 52 秒,而顺序版本需要 50 秒来执行

是什么导致了这种性能下降?同步是问题还是写入单个工作簿是问题?

【问题讨论】:

  • 我不确定这算作退化。时间跨度足够长,其他进程可能会干扰,我不确定百分比差异是否显着。
  • 顺便说一句,您的基准到底是什么?您总共进行了多少次跑步,每个类别中最快的跑步次数是多少?
  • 实际的方法是一个接一个地依次调用函数。运行次数只有一次。
  • 虽然我确实运行了多次来仔细检查。结果每次都一样
  • 写入少量的数据,说一些需要 1 秒的东西,运行 100 次并选择最小值。

标签: multithreading python-3.x parallel-processing xlsxwriter


【解决方案1】:

在正常操作中,xlsxwriter 将数据存储在内存中,并在close() 阶段将该数据写入文件,然后压缩这些文件。在任何相当大的 xlsxwriter 程序中,文件写入操作占执行时间的大部分。

您看不到加速的原因可能是线程在到达程序的close() 部分时已重新加入。

我认为在构造函数中使用{'constant_memory': True} 可能会从线程版本中获得更好的性能,因为它使用中间文件而不是内存。但是,使用您的程序进行快速测试,它不会。

加速大型 xlsxwriter 程序的更好方法是使用pypy。对于程序的非线程版本,参考系统的执行时间从 46.7s (Python2) 到 8.2s (PyPy) 或快了将近 6 倍。

事实上,pypy 提供的性能接近于 xlsxwriter libxlsxwriter 的纯 C 实现,对于更大的数据集,它比 Python 版本快大约 10 倍。

【讨论】:

  • 所以这原来是python的一个限制。如果将 xlsxwriter 替换为 openpyxl,您认为性能如何?
  • openpyxl和xlsxwriter的性能应该差不多。
  • 使用 pypy,执行时间减少到 17 秒(约快 3 倍)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-22
  • 2019-02-23
  • 2016-03-02
  • 2018-08-13
  • 1970-01-01
  • 2020-08-27
相关资源
最近更新 更多