Skip to content

Commit 8a4dd06

Browse files
committed
Minor optimizations to ReplayBuffer.shift and a couple other small members
1 parent 1b80edf commit 8a4dd06

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

sc2reader/utils.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,22 @@ def __init__(self, file):
6262
# setup shift defaults
6363
self.bit_shift = 0
6464
self.last_byte = None
65+
66+
#Extra optimization stuff
67+
self.lo_masks = [0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF]
68+
self.lo_masks_inv = [0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF]
69+
self.hi_masks = [0xFF ^ mask for mask in self.lo_masks]
70+
self.hi_masks_inv = [0xFF ^ mask for mask in self.lo_masks_inv]
6571

6672
'''
6773
Additional Properties
6874
'''
6975
@property
70-
def left(self): return self.length - self.cursor
71-
76+
def left(self): return self.length - self.io.tell()
7277
@property
7378
def empty(self): return self.left==0
7479
@property
75-
def cursor(self): return self.tell()
80+
def cursor(self): return self.io.tell()
7681

7782
'''
7883
Stream manipulation functions
@@ -234,6 +239,7 @@ def read_range(self, start, end):
234239
self.io.seek(current)
235240
return ret
236241

242+
237243
'''
238244
Base read functions
239245
'''
@@ -247,25 +253,28 @@ def shift(self, bits):
247253
byte-aligned byte.
248254
"""
249255
try:
250-
if bits == 0:
251-
return 0
256+
#declaring locals instead of accessing dict on multiple use seems faster
257+
bit_shift = self.bit_shift
258+
new_shift = bit_shift+bits
252259

253-
elif bits <= (8-self.bit_shift):
254-
#Grab a new byte if the currently loaded one is exhausted
255-
if self.bit_shift == 0:
260+
#make sure there are enough bits left in the byte
261+
if new_shift <= 8:
262+
if not bit_shift:
256263
self.last_byte = ord(self.io.read(1))
257264

258-
#Get the requested bits from the byte, and adjust state
259-
ret = (self.last_byte >> self.bit_shift) & (2**bits-1)
260-
self.bit_shift = (self.bit_shift + bits) % 8
265+
#using a bit_mask_array tested out to be 20% faster, go figure
266+
ret = (self.last_byte >> bit_shift) & self.lo_masks[bits]
267+
#using an if for the special case tested out to be faster, hrm
268+
self.bit_shift = 0 if new_shift == 8 else new_shift
261269
return ret
262270

263271
else:
264272
msg = "Cannot shift off %s bits. Only %s bits remaining."
265273
raise ValueError(msg % (bits, 8-self.bit_shift))
274+
266275
except TypeError:
267-
raise EOFError("Cannot shift new byte. End of buffer reached")
268-
276+
raise EOFError("Cannot shift requested bits. End of buffer reached")
277+
269278
def read(self, bytes=0, bits=0):
270279
try:
271280
bytes, bits = bytes+bits/8, bits%8
@@ -345,7 +354,6 @@ def read(self, bytes=0, bits=0):
345354

346355
except TypeError:
347356
raise EOFError("Cannot read requested bits/bytes. End of buffer reached")
348-
349357

350358
class PersonDict(dict):
351359
"""Delete is supported on the pid index only"""

0 commit comments

Comments
 (0)