在文件中写入大量数据的最快方法

ajk*_*hol 11 python performance file

我试图创建一个随机的真实,整数,字母数字,字母字符串,然后写入文件,直到文件大小达到10MB.

代码如下.

import string
import random
import time
import sys


class Generator():
    def __init__(self):
        self.generate_alphabetical_strings()
        self.generate_integers()
        self.generate_alphanumeric()
        self.generate_real_numbers()

    def generate_alphabetical_strings(self):
        return ''.join(random.choice(string.ascii_lowercase) for i in range(12))

    def generate_integers(self):
        return ''.join(random.choice(string.digits) for i in range(12))

    def generate_alphanumeric(self):
        return ''.join(random.choice(self.generate_alphabetical_strings() +
                                     self.generate_integers()) for i in range(12))

    def _insert_dot(self, string, index):
        return string[:index].__add__('.').__add__(string[index:])


    def generate_real_numbers(self):
        rand_int_string = ''.join(random.choice(self.generate_integers()) for i in range(12))
        return self._insert_dot(rand_int_string, random.randint(0, 11))


from time import process_time
import os

a = Generator()

t = process_time()
inp = open("test.txt", "w")
lt = 10 * 1000 * 1000
count = 0
while count <= lt:
    inp.write(a.generate_alphanumeric())
    count += 39
inp.close()

elapsed_time = process_time() - t
print(elapsed_time)
Run Code Online (Sandbox Code Playgroud)

完成大约需要225.953125秒.我怎样才能提高这个程序的速度?请提供一些代码见解?

Jan*_*cke 31

观察到"缓慢"的两个主要原因:

  • 你的while循环很慢,它有大约一百万次迭代.
  • 您没有正确使用I/O缓冲.不要进行这么多系统调用.目前,你打电话write()约一百万次.

首先在Python数据结构中创建数据,然后write()只调用一次.

这更快:

t0 = time.time()
open("bla.txt", "wb").write(''.join(random.choice(string.ascii_lowercase) for i in xrange(10**7)))
d = time.time() - t0
print "duration: %.2f s." % d
Run Code Online (Sandbox Code Playgroud)

输出: duration: 7.30 s.

现在程序花费大部分时间生成数据,即在random东西中.您可以通过替换random.choice(string.ascii_lowercase)例如,轻松地看到"a".然后测量的时间在我的机器上下降到一秒以下.

如果你想更接近地看到你的机器在写入磁盘时的速度有多快,那么在将其写入磁盘之前,使用Python最快(?)的方式生成较大的数据:

>>> t0=time.time(); chunk="a"*10**7; open("bla.txt", "wb").write(chunk); d=time.time()-t0; print "duration: %.2f s." % d
duration: 0.02 s.
Run Code Online (Sandbox Code Playgroud)

  • 您正在写入磁盘.写入磁盘是一个复杂的物理和逻辑过程.它涉及许多机制和控制.告诉磁盘要快得多*"在这里,这是10 MB的数据,写下来吧!" 而不是告诉它数百万次"在这里,这是1字节的数据,写下它!".因此,操作系统有一种机制来"收集"进程想要写入磁盘的数据,然后再将其保存到磁盘.但是,如果您明确告诉操作系统写入一小部分,那么它就会这样做.你这样做了,这很慢.看我的编辑. (9认同)
  • @AaronDigulla:如果你在调用Python的`open()`时没有指定`buffering`参数,通常会根据"系统默认值"应用(小)缓冲区.未记录此缓冲区的大小.对于某些版本的glibc,这里有人确定它是8 kB:http://stackoverflow.com/a/18194856/145400.对于某些应用程序,使用`buffering`参数增加缓冲区大小是有意义的.没有一般性声明,但基准测试有帮助.有时通过https://docs.python.org/2/library/stringio.html首先在内存中显式收集数据是有意义的. (3认同)
  • 你是什​​么意思正确使用IO缓冲? (2认同)