我有一个很长的字符串,差不多一兆字节,我需要写一个文本文件。常规
file = open("file.txt","w")
file.write(string)
file.close()
有效,但速度太慢,有没有办法让我写得更快?
我正在尝试将数百万位数字写入文本文件
该数字大约为math.factorial(67867957)
这是分析中显示的内容:
203 function calls (198 primitive calls) in 0.001 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 re.py:217(compile)
1 0.000 0.000 0.000 0.000 re.py:273(_compile)
1 0.000 0.000 0.000 0.000 sre_compile.py:172(_compile_charset)
1 0.000 0.000 0.000 0.000 sre_compile.py:201(_optimize_charset)
4 0.000 0.000 0.000 0.000 sre_compile.py:25(_identityfunction)
3/1 0.000 0.000 0.000 0.000 sre_compile.py:33(_compile)
1 0.000 0.000 0.000 0.000 sre_compile.py:341(_compile_info)
2 0.000 0.000 0.000 0.000 sre_compile.py:442(isstring)
1 0.000 0.000 0.000 0.000 sre_compile.py:445(_code)
1 0.000 0.000 0.000 0.000 sre_compile.py:460(compile)
5 0.000 0.000 0.000 0.000 sre_parse.py:126(__len__)
12 0.000 0.000 0.000 0.000 sre_parse.py:130(__getitem__)
7 0.000 0.000 0.000 0.000 sre_parse.py:138(append)
3/1 0.000 0.000 0.000 0.000 sre_parse.py:140(getwidth)
1 0.000 0.000 0.000 0.000 sre_parse.py:178(__init__)
10 0.000 0.000 0.000 0.000 sre_parse.py:183(__next)
2 0.000 0.000 0.000 0.000 sre_parse.py:202(match)
8 0.000 0.000 0.000 0.000 sre_parse.py:208(get)
1 0.000 0.000 0.000 0.000 sre_parse.py:351(_parse_sub)
2 0.000 0.000 0.000 0.000 sre_parse.py:429(_parse)
1 0.000 0.000 0.000 0.000 sre_parse.py:67(__init__)
1 0.000 0.000 0.000 0.000 sre_parse.py:726(fix_flags)
1 0.000 0.000 0.000 0.000 sre_parse.py:738(parse)
3 0.000 0.000 0.000 0.000 sre_parse.py:90(__init__)
1 0.000 0.000 0.000 0.000 {built-in method compile}
1 0.001 0.001 0.001 0.001 {built-in method exec}
17 0.000 0.000 0.000 0.000 {built-in method isinstance}
39/38 0.000 0.000 0.000 0.000 {built-in method len}
2 0.000 0.000 0.000 0.000 {built-in method max}
8 0.000 0.000 0.000 0.000 {built-in method min}
6 0.000 0.000 0.000 0.000 {built-in method ord}
48 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
5 0.000 0.000 0.000 0.000 {method 'find' of 'bytearray' objects}
1 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects}
答案 0 :(得分:2)
您的问题是str(long)
对于Python中的大型intergers(数百万位)来说非常慢。 It is a quadratic operation (in number of digits) in Python,即对于~1e8位数,可能需要~1e16次操作才能将整数转换为十进制字符串。
写入文件500MB不应该花费数小时,例如:
$ python3 -c 'open("file", "w").write("a"*500*1000000)'
几乎立即返回。 ls -l file
确认文件已创建且具有预期大小。
计算math.factorial(67867957)
(结果有~500M位)可能需要几个小时但是使用pickle
保存它是瞬间的:
import math
import pickle
n = math.factorial(67867957) # takes a long time
with open("file.pickle", "wb") as file:
pickle.dump(n, file) # very fast (comparatively)
使用n = pickle.load(open('file.pickle', 'rb'))
加载它只需不到一秒钟。
str(n)
仍在运行(50小时后)。
要快速获得十进制表示,您可以use gmpy2
:
$ python -c'import gmpy2;open("file.gmpy2", "w").write(str(gmpy2.fac(67867957)))'
我的机器上只需不到10分钟。
答案 1 :(得分:0)
好的,这真的不是一个答案,更多的是证明你推迟错误的推理
首先测试一个大字符串的写入速度
import timeit
def write_big_str(n_bytes=1000000):
with open("test_file.txt","wb") as f:
f.write("a"*n_bytes)
print timeit.timeit("write_big_str()","from __main__ import write_big_str",number=100)
你应该看到一个相当可观的速度(并且重复它100次)
接下来我们将看到将一个非常大的数字转换为str
需要多长时间import timeit,math
n = math.factorial(200000)
print timeit.timeit("str(n)","from __main__ import n",number=1)
它可能需要大约10秒(这是一个百万位数字),授予的速度很慢......但不是很慢的时间(好吧,它很慢转换为字符串:P ...但仍然不需要几个小时) (好吧我的盒子花了243秒钟,我想:P)