Pythonでは、100万個の32ビットintを2メガバイトのメモリにソートできるかどうかを冗談で尋ねられました。 考えながら、バッファメモリを使用したI / Oメカニズムを使用するようになりました。
一般的に、これは単なる漫画の質問です-バイナリ表現を前提として、データのみが4メガバイトを占有します! 確かに、あなたはトリックのために行くことができます-100万の32ビットintを含むファイルを取ります。 最小量のメモリを使用してそれらをソートする方法は? 何らかの種類のマージソートを行う必要があります。このソートでは、小さなデータがソートされて一時ファイルに書き込まれ、その後、一時ファイルがマージされて最終結果が得られます。
ここに私の解決策があります:
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
Copy Source | Copy HTML #!/usr/bin/env python3.0 import sys, array, tempfile, heapq assert array . array ( 'i' ).itemsize == 4 def intsfromfile (f): while True: a = array . array ( 'i' ) a.fromstring(f.read( 4000 )) if not a: break for x in a: yield x iters = [] while True: a = array . array ( 'i' ) a.fromstring( sys .stdin.buffer.read( 40000 )) if not a: break f = tempfile .TemporaryFile() array . array ( 'i' , sorted (a)).tofile(f) f.seek( 0 ) iters.append( intsfromfile (f)) a = array . array ( 'i' ) for x in heapq .merge(*iters): a.append(x) if len (a) >= 1000 : a.tofile( sys .stdout.buffer) del a[:] if a: a.tofile( sys .stdout.buffer)
3年前のLinuxベースのスタッフでは、100万個のランダムな32ビット整数を含む入力ファイルからデータを読み取るのに5.4秒かかりました。 メモリから直接データを読み取る場合、ソートに2秒かかることを考えると、これはそれほど悪くありません。
Copy Source | Copy HTML
- #!/ usr / bin / env python3.0
- インポート sys、配列
- a = 配列 。 配列 ( 'i' 、 sys .stdin.buffer.read())
- a = リスト (a)
- a.sort()
- a = 配列 。 配列 ( 'i' 、a)
- a.tofile( sys .stdout.buffer)
ソートに戻りましょう。 最初の3行は明らかです。
Copy Source | Copy HTML
- #!/ usr / bin / env python3.0
- sys、配列、tempfile、heapqをインポートします
- 配列を アサートします。 配列 ( 'i' ).itemsize == 4
最初の行は、Python 3.0を使用していることを示しています。 2行目は必要なモジュールをインポートします。 3行目では、64ビットシステムで割り込みが発生します。intは32ビットではありません-移植可能なコードを書く仕事はありませんでした。
次に、ファイルからintを読み取る関数を宣言しました。
Copy Source | Copy HTML
- def intsfromfile (f):
- Trueの場合:
- a = 配列 。 配列 ( 'i' )
- a.fromstring(f.read( 4000 ))
- そうでない場合 :
- 破る
- aのxに対して:
- 収量 x
これは、アルゴリズムの最適化が行われる場所です。一度に最大1000のintを読み取り、それらを1つずつ発行します。 最初は、バッファリングを使用しませんでした-この関数は、ファイルから4バイトを読み取り、整数に変換して返しました。 しかし、それは4倍遅くなりました! ファイルに十分なデータがない場合は
fromfile()
メソッドがエラーを返すので
a.fromfile(f, 1000)
使用できないことに注意してください。また、ファイル内の任意の数のintにコード自体を適合させたいと考えました。
次は入力ループです。 入力ファイルから10'000 intの断片を周期的に読み取り、メモリ内でソートして一時ファイルに書き込みます。 次に、上記のintsfromfile()関数を使用して、最終段階で必要になるイテレーターのリストに一時ファイルのイテレーターを追加します。
Copy Source | Copy HTML
- iters = []
- Trueの場合:
- a = 配列 。 配列 ( 'i' )
- a.fromstring( sys .stdin.buffer.read( 40000 ))
- そうでない場合 :
- 破る
- f = tempfile .TemporaryFile()
- 配列 配列 ( 'i' 、 ソート済み (a))。tofile(f)
- f.seek( 0 )
- iters.append(intsfromfile(f))
したがって、入力された100万intに対して、それぞれ10,000個の値を持つ100個の一時ファイルが作成されます。
最後に、これらすべてのファイル(各ファイルは既にソートされています)をマージします。 heapqモジュールには、この問題を解決するための素晴らしい関数が含まれています:
heapq.merge(iter1, iter2, ... )
、各入力パラメーター自体が目的の順序で値を渡すシーケンスで入力パラメーターをスキップするイテレーターを返します(このように)ケース)。
Copy Source | Copy HTML
- a = 配列 。 配列 ( 'i' )
- heapq .mergeのxの場合(* iters):
- a.append(x)
- len (a)> = 1000の場合 :
- a.tofile( sys .stdout.buffer)
- デル [:]
- 場合 :
- a.tofile( sys .stdout.buffer)
これは、バッファリングされた入力/出力が必要なもう1つのケースです。個々の値をファイルに書き込むと、使用可能になり次第、アルゴリズムの速度が半分になります。 入力と出力でバッファリングを使用して、実行速度を10倍に上げることができました!