2017-09-19 75 views
5

Używam modułu pythonów bz2 do generowania (i kompresowania) dużego pliku jsonl (skompresowanego bzip2 17 GB).Czy jest możliwe zrównoleglenie dekompresji bz2?

Jednak, gdy później próbuję dekompresować go za pomocą pbzip2, wydaje się, że tylko jeden rdzeń CPU do dekompresji, który jest dość powolny.

Kiedy kompresuję go za pomocą pbzip2, może on korzystać z wielu rdzeni podczas dekompresji. Czy istnieje sposób kompresji w Pythonie w formacie kompatybilnym z pbzip2?

import bz2,sys 
from Queue import Empty 
#... 
compressor = bz2.BZ2Compressor(9) 
f = open(path, 'a') 

    try: 
     while 1: 
      m = queue.get(True, 1*60) 
      f.write(compressor.compress(m+"\n")) 
    except Empty, e: 
     pass 
    except Exception as e: 
     traceback.print_exc() 
    finally: 
     sys.stderr.write("flushing") 
     f.write(compressor.flush()) 
     f.close() 
+0

Z tego, co przeczytałem, równoległe operacje na dyskach I/O to [zły pomysł] (https://stackoverflow.com/a/1993707/3727854). Biorąc to pod uwagę [ta odpowiedź może być istotna] (https://stackoverflow.com/a/42012661/3727854) na to pytanie. –

+1

@JamesDraper dysku I/O nie będzie czynnikiem ograniczającym ... obliczenia bzip są powolne – o11c

+1

@worenga Zwróć uwagę, że jsonl jest niebezpiecznym formatem, jeśli możesz użyć liczb najwyższego poziomu, ponieważ są one podatne na obcięcie. Json-seq rozwiązuje ten problem, nakazując błąd. – o11c

Odpowiedz

2

pbzip2 strumień jest niczym więcej niż łączenie wielu bzip2 strumieni.

Przykładem pomocą powłoki:

bzip2 </usr/share/dict/words> words_x_1.bz2 
cat words_x_1.bz2{,,,,,,,,,} > words_x_10.bz2 
time bzip2 -d <words_x_10.bz2> /dev/null 
time pbzip2 -d <words_x_10.bz2> /dev/null 

Nigdy nie używany moduł Pythona bz2, ale to powinno być łatwe do zamknięcia/ponownego otwarcia strumienia w 'a' trybie ppend, co tak wiele bajtów, aby uzyskać ten sam wynik. Zauważ, że jeśli BZ2File jest skonstruowany z istniejącego obiektu podobnego do pliku, zamknięcie BZ2File nie zamknie strumienia bazowego (tutaj właśnie tego chcesz).

Nie zmierzyłem ile bajtów jest optymalnych do wyodrębniania, ale zgaduję, że co 1-20 megabajtów - zdecydowanie musi być większy niż rozmiar bloku bzip2 (900k).

Należy również pamiętać, że w przypadku rejestrowania skompresowanych i nieskompresowanych przesunięć każdego fragmentu można uzyskać dość wydajny dostęp losowy. W ten sposób działa program dictzip, choć bazuje on na gzip.