comparison mercurial/branchmap.py @ 31379:906be86990c4

rbc: use struct unpack_from and pack_into instead of unpack and pack These functions were introduced in Python 2.5 and are faster and simpler than the old ones ... mainly because we can avoid intermediate buffers: $ python -m timeit -s "_rbcrecfmt='>4sI'" -s 's = "x"*10000' -s 'from struct import unpack' 'unpack(_rbcrecfmt, buffer(s, 16, 8))' 1000000 loops, best of 3: 0.543 usec per loop $ python -m timeit -s "_rbcrecfmt='>4sI'" -s 's = "x"*10000' -s 'from struct import unpack_from' 'unpack_from(_rbcrecfmt, s, 16)' 1000000 loops, best of 3: 0.323 usec per loop $ python -m timeit -s "from array import array" -s "_rbcrecfmt='>4sI'" -s "s = array('c')" -s 's.fromstring("x"*10000)' -s 'from struct import pack' -s "rec = array('c')" 'rec.fromstring(pack(_rbcrecfmt, "asdf", 7))' 1000000 loops, best of 3: 0.364 usec per loop $ python -m timeit -s "from array import array" -s "_rbcrecfmt='>4sI'" -s "s = array('c')" -s 's.fromstring("x"*10000)' -s 'from struct import pack_into' -s "rec = array('c')" -s 'rec.fromstring("x"*100)' 'pack_into(_rbcrecfmt, rec, 0, "asdf", 7)' 1000000 loops, best of 3: 0.229 usec per loop
author Mads Kiilerich <madski@unity3d.com>
date Wed, 19 Oct 2016 02:46:35 +0200
parents 37acdf027ae2
children 7dd2f51f38ac
comparison
equal deleted inserted replaced
31378:b6f5af372c0c 31379:906be86990c4
21 scmutil, 21 scmutil,
22 util, 22 util,
23 ) 23 )
24 24
25 calcsize = struct.calcsize 25 calcsize = struct.calcsize
26 pack = struct.pack 26 pack_into = struct.pack_into
27 unpack = struct.unpack 27 unpack_from = struct.unpack_from
28 28
29 def _filename(repo): 29 def _filename(repo):
30 """name of a branchcache file for a given repo or repoview""" 30 """name of a branchcache file for a given repo or repoview"""
31 filename = "cache/branch2" 31 filename = "cache/branch2"
32 if repo.filtername: 32 if repo.filtername:
404 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize: 404 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
405 return self._branchinfo(rev) 405 return self._branchinfo(rev)
406 406
407 # fast path: extract data from cache, use it if node is matching 407 # fast path: extract data from cache, use it if node is matching
408 reponode = changelog.node(rev)[:_rbcnodelen] 408 reponode = changelog.node(rev)[:_rbcnodelen]
409 cachenode, branchidx = unpack( 409 cachenode, branchidx = unpack_from(_rbcrecfmt, self._rbcrevs, rbcrevidx)
410 _rbcrecfmt, util.buffer(self._rbcrevs, rbcrevidx, _rbcrecsize))
411 close = bool(branchidx & _rbccloseflag) 410 close = bool(branchidx & _rbccloseflag)
412 if close: 411 if close:
413 branchidx &= _rbcbranchidxmask 412 branchidx &= _rbcbranchidxmask
414 if cachenode == '\0\0\0\0': 413 if cachenode == '\0\0\0\0':
415 pass 414 pass
449 return b, close 448 return b, close
450 449
451 def _setcachedata(self, rev, node, branchidx): 450 def _setcachedata(self, rev, node, branchidx):
452 """Writes the node's branch data to the in-memory cache data.""" 451 """Writes the node's branch data to the in-memory cache data."""
453 rbcrevidx = rev * _rbcrecsize 452 rbcrevidx = rev * _rbcrecsize
454 rec = bytearray(pack(_rbcrecfmt, node, branchidx))
455 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize: 453 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
456 self._rbcrevs.extend('\0' * 454 self._rbcrevs.extend('\0' *
457 (len(self._repo.changelog) * _rbcrecsize - 455 (len(self._repo.changelog) * _rbcrecsize -
458 len(self._rbcrevs))) 456 len(self._rbcrevs)))
459 self._rbcrevs[rbcrevidx:rbcrevidx + _rbcrecsize] = rec 457 pack_into(_rbcrecfmt, self._rbcrevs, rbcrevidx, node, branchidx)
460 self._rbcrevslen = min(self._rbcrevslen, rev) 458 self._rbcrevslen = min(self._rbcrevslen, rev)
461 459
462 tr = self._repo.currenttransaction() 460 tr = self._repo.currenttransaction()
463 if tr: 461 if tr:
464 tr.addfinalize('write-revbranchcache', self.write) 462 tr.addfinalize('write-revbranchcache', self.write)