我试图将一个非常大的文本文件(大约150 GB)批处理为几个较小的文本文件(大约10 GB)。
我的一般流程是:
# iterate over file one line at a time
# accumulate batch as string
--> # given a certain count that correlates to the size of my current accumulated batch and when that size is met: (this is where I am unsure)
# write to file
# accumulate size count
我有一个粗略的度量标准来计算何时进行批处理(何时需要所需的批处理大小),但不清楚如何计算给定批处理写入磁盘的频率。例如,如果我的批处理大小为10 GB,我假设我将需要迭代写入而不是将整个10 GB批处理保存在内存中。我显然不想写比我多的东西,因为这可能会很昂贵。
您是否会想使用粗略的计算方法或技巧来弄清楚何时为诸如此类的任务(例如大小与内存等)写入磁盘?
假设您的大文件是简单的非结构化文本,即这对像JSON这样的结构化文本不利,这是读取每一行的一种替代方法:读取输入文件的大二进制位,直到达到块大小,然后读取几行,然后关闭当前的输出文件,然后移至下一个。
我将其与@tdelaney代码逐行比较,该代码采用与我的代码相同的块大小进行修改-该代码花了250秒的时间将12GiB输入文件分割成6x2GiB的块,而这花了大约50s,所以速度可能快了五倍,看起来像我的SSD上的I / O的读写速度大于200MiB / s,而逐行的读写速度则为40-50MiB / s。
我关闭了缓冲功能,因为没有太多意义。咬的大小和缓冲设置可能是可调的,以提高性能,没有尝试任何其他设置,因为对我而言,它似乎还是受I / O约束的。
import time
outfile_template = "outfile-{}.txt"
infile_name = "large.text"
chunksize = 2_000_000_000
MEB = 2**20 # mebibyte
bitesize = 4_000_000 # the size of the reads (and writes) working up to chunksize
count = 0
starttime = time.perf_counter()
infile = open(infile_name, "rb", buffering=0)
outfile = open(outfile_template.format(count), "wb", buffering=0)
while True:
byteswritten = 0
while byteswritten < chunksize:
bite = infile.read(bitesize)
# check for EOF
if not bite:
break
outfile.write(bite)
byteswritten += len(bite)
# check for EOF
if not bite:
break
for i in range(2):
l = infile.readline()
# check for EOF
if not l:
break
outfile.write(l)
# check for EOF
if not l:
break
outfile.close()
count += 1
print( count )
outfile = open(outfile_template.format(count), "wb", buffering=0)
outfile.close()
infile.close()
endtime = time.perf_counter()
elapsed = endtime-starttime
print( f"Elapsed= {elapsed}" )
注意:虽然没有证据表明它确实丢失了任何内容,但我没有进行详尽的测试,也不会丢失数据,您应该验证自己。
通过检查何时在块末尾查看剩余的数据量来增加健壮性可能很有用,因此您不会以最后一个输出文件的长度为0(或小于bitizeize)为结尾
HTH兔子
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句