2016-04-24 11 views
6

私は30メガバイトの.TXTファイルを持っているの読み方、ループ用に1GBのRAMを割り当てる)は、ファイルを完全に読み取るのに45分以上かかります。 私はインターネット上で見つかったすべてのメソッドは、各行が小さいという事実に動作しているようですので、メモリの消費量は、ファイル内の最大の行のみと同じ大きさです。ここに私が使ってきたコードがあります。種々のライン1つの行から番号を分割以外</em><br> 残念ながら、すべてのメソッドは、私が試したデータ<em>の<strong></strong>ライン(30百万桁の数字)(<code>mmap.read()</code>、<code>readline()</code>で、超大型ワンライナーテキストファイル

start = time.clock() 
z = open('Number.txt','r+') 
m = mmap.mmap(z.fileno(), 0) 
global a 
a = int(m.read()) 
z.close() 
end = time.clock() 
secs = (end - start) 
print("Number read in","%s" % (secs),"seconds.", file=f) 
print("Number read in","%s" % (secs),"seconds.") 
f.flush() 
del end,start,secs,z,m 

。私はむしろやっていないでしょう、より良い部分を必要としないクリーンな方法がありますか?ところで

、私は必ずしもテキストファイルを使用する必要はありません。

私が持っています。Windows 8.1 64ビット、16ギガバイトRAM、Pythonの3.5.1

+1

30MBのファイルを読むのは簡単です。遅いint(filecontent)です。 –

+0

あなたがそれを変換すると、あなたが選んだタイプによって多かれ少なかれ近似が生じることにご存知ですか?あなたはそれのすべてのギザギザの数字を保持しません。 – Roberto

+0

...もちろん、その数で作業できるかもしれませんが、標準タイプは1桁で3,000万の有効数字を保持しません。彼らは近づくでしょう。それを行う方法を探したり、実装したりする必要があります。 – Roberto

答えて

1

私は文字列を数値に変換するにはgmpy2モジュールを使用。

start = time.clock() 
z=open('Number.txt','r+') 
data=z.read() 
global a 
a=gmpy2.mpz(data) 
end = time.clock() 
secs = (end - start) 
print("Number read in","%s" % (secs),"seconds.", file=f) 
print("Number read in","%s" % (secs),"seconds.") 
f.flush() 
del end,secs,start,z,data 

それははるかに遅く、3秒で働いていたが、少なくともそれは私に整数値を与えました。

貴重なご回答をいただきありがとうございますが、できるだけ早くこれをマークします。

3

は、30メガバイトのテキストファイルを読むために非常に長いを取るべきではない、現代のハードドライブは1秒未満でこれを行うことができるはずこの場合には正常に動作する必要があり、標準のpythonファイルIOを使用して

(アクセス時間カウントされません):私のラップトップ上でこれを使用して

with open('my_file', 'r') as handle: 
    content = handle.read() 

して第2のよりもはるかに少ない時間を与えます。

しかし、これらの30 MBを整数に変換すると、 のボトルネックになります。なぜなら、pythonはこれをlongデータ型で表すことができないからです。

ただし、それは主に浮動小数点演算のために設計されて、decimalモジュールで試してみることができます。そのほかに

は、速いかもしれません(そしておそらく後に番号を持ついくつかの仕事をしたいので、そのようなライブラリを使用するように理にかなって)当然のnumpyのは、そこにあります。

+0

Numpyは同じ問題を抱えていませんか?彼らは両方とも非常に大きな文字列を数値に変換しようとしています。 –

11

読んでファイルが(< 1S)速いです:あなたが生として番号を保存する場合

z=int(data) # still waiting... 

:、それは遅いです整数に30百万桁の文字列を変換する

with open('number.txt') as f: 
    data = f.read() 

ビッグエンディアンまたはリトルエンディアンのバイナリデータの場合は、int.from_bytes(data,'big')がはるかに高速です。

私は私の数学をした場合は、右(_注記は、Pythonの対話インタプリタで「最後の行の答え」を意味する):

>>> import math 
>>> math.log(10)/math.log(2) # Number of bits to represent a base 10 digit. 
3.3219280948873626 
>>> 30000000*_    # Number of bits to represent 30M-digit #. 
99657842.84662087 
>>> _/8      # Number of bytes to represent 30M-digit #. 
12457230.35582761    # Only ~12MB so file will be smaller :^) 
>>> import os 
>>> data=os.urandom(12457231) # Generate some random bytes 
>>> z=int.from_bytes(data,'big') # Convert to integer (<1s) 
99657848 
>>> math.log10(z) # number of base-10 digits in number. 
30000001.50818886 

EDIT:FYI、私の数学は右ではなかったが、私はそれを修正します。気付かずに10 upvotesしてくれてありがとう:^)

+0

int.from_bytes(data、 'big')を使用しようとすると、 "TypeError:ユニコードオブジェクトをバイトに変換できません" –

+1

@ Master-chipバイナリデータを取得するために 'rb'で読み込みます。 –

+0

おっと、恥ずかしかったです。それは素晴らしい作品、それは0.39秒でそれを読んで、ありがとう。 –

関連する問題

 関連する問題