1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
from optparse import OptionParser
from time import perf_counter
from collections import Counter
from bitarray import bitarray
from bitarray.util import _huffman_tree
from huffman import (huff_code, write_dot, print_code,
make_tree, iterdecode)
def main():
p = OptionParser("usage: %prog [options] [FILE]")
p.add_option(
'-p', '--print',
action="store_true",
help="print Huffman code")
p.add_option(
'-t', '--tree',
action="store_true",
help="store the tree as a .dot file")
opts, args = p.parse_args()
if len(args) == 0:
filename = 'README'
elif len(args) == 1:
filename = args[0]
else:
p.error('only one argument expected')
with open(filename, 'rb') as fi:
plain = bytearray(fi.read())
t0 = perf_counter()
freq = Counter(plain)
print('count: %9.3f ms' % (1000.0 * (perf_counter() - t0)))
t0 = perf_counter()
tree = _huffman_tree(freq)
print('tree: %9.3f ms' % (1000.0 * (perf_counter() - t0)))
if opts.tree:
write_dot(tree, 'tree.dot', 0 in plain)
code = huff_code(tree)
if opts.print:
print_code(freq, code)
if opts.tree:
# create tree from code (no frequencies)
write_dot(make_tree(code), 'tree_raw.dot', 0 in plain)
a = bitarray()
t0 = perf_counter()
a.encode(code, plain)
print('C encode: %9.3f ms' % (1000.0 * (perf_counter() - t0)))
# Time the decode function above
t0 = perf_counter()
res = bytearray(iterdecode(tree, a))
Py_time = perf_counter() - t0
print('Py decode: %9.3f ms' % (1000.0 * Py_time))
assert res == plain
# Time the decode method which is implemented in C
t0 = perf_counter()
res = bytearray(a.decode(code))
C_time = perf_counter() - t0
print('C decode: %9.3f ms' % (1000.0 * C_time))
assert res == plain
print('Ratio: %f' % (Py_time / C_time))
if __name__ == '__main__':
main()
|