29
29
_MINUS_INF = float ("-inf" )
30
30
_INITIAL_MMAP_SIZE = 1 << 20
31
31
32
+ _pack_integer = struct .Struct (b'i' ).pack_into
33
+ _pack_double = struct .Struct (b'd' ).pack_into
34
+ _unpack_integer = struct .Struct (b'i' ).unpack_from
35
+ _unpack_double = struct .Struct (b'd' ).unpack_from
36
+
32
37
33
38
class CollectorRegistry (object ):
34
39
'''Metric collector registry.
@@ -353,10 +358,10 @@ def __init__(self, filename, read_mode=False):
353
358
self ._m = mmap .mmap (self ._f .fileno (), self ._capacity )
354
359
355
360
self ._positions = {}
356
- self ._used = struct . unpack_from ( b'i' , self ._m , 0 )[0 ]
361
+ self ._used = _unpack_integer ( self ._m , 0 )[0 ]
357
362
if self ._used == 0 :
358
363
self ._used = 8
359
- struct . pack_into ( b'i' , self ._m , 0 , self ._used )
364
+ _pack_integer ( self ._m , 0 , self ._used )
360
365
else :
361
366
if not read_mode :
362
367
for key , _ , pos in self ._read_all_values ():
@@ -376,19 +381,27 @@ def _init_value(self, key):
376
381
377
382
# Update how much space we've used.
378
383
self ._used += len (value )
379
- struct . pack_into ( b'i' , self ._m , 0 , self ._used )
384
+ _pack_integer ( self ._m , 0 , self ._used )
380
385
self ._positions [key ] = self ._used - 8
381
386
382
387
def _read_all_values (self ):
383
388
"""Yield (key, value, pos). No locking is performed."""
389
+
384
390
pos = 8
385
- while pos < self ._used :
386
- encoded_len = struct .unpack_from (b'i' , self ._m , pos )[0 ]
391
+
392
+ # cache variables to local ones and prevent attributes lookup
393
+ # on every loop iteration
394
+ used = self ._used
395
+ data = self ._m
396
+ unpack_from = struct .unpack_from
397
+
398
+ while pos < used :
399
+ encoded_len = _unpack_integer (data , pos )[0 ]
387
400
pos += 4
388
- encoded = struct . unpack_from ('{0}s' . format ( encoded_len ).encode (), self . _m , pos )[0 ]
401
+ encoded = unpack_from (( '%ss' % encoded_len ).encode (), data , pos )[0 ]
389
402
padded_len = encoded_len + (8 - (encoded_len + 4 ) % 8 )
390
403
pos += padded_len
391
- value = struct . unpack_from ( b'd' , self . _m , pos )[0 ]
404
+ value = _unpack_double ( data , pos )[0 ]
392
405
yield encoded .decode ('utf-8' ), value , pos
393
406
pos += 8
394
407
@@ -402,14 +415,14 @@ def read_value(self, key):
402
415
self ._init_value (key )
403
416
pos = self ._positions [key ]
404
417
# We assume that reading from an 8 byte aligned value is atomic
405
- return struct . unpack_from ( b'd' , self ._m , pos )[0 ]
418
+ return _unpack_double ( self ._m , pos )[0 ]
406
419
407
420
def write_value (self , key , value ):
408
421
if key not in self ._positions :
409
422
self ._init_value (key )
410
423
pos = self ._positions [key ]
411
424
# We assume that writing to an 8 byte aligned value is atomic
412
- struct . pack_into ( b'd' , self ._m , pos , value )
425
+ _pack_double ( self ._m , pos , value )
413
426
414
427
def close (self ):
415
428
if self ._f :
0 commit comments