D1392: bundle2: inline changegroup.readexactly()

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Tue Nov 14 01:26:20 EST 2017


indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Profiling reveals this loop is pretty tight. Literally any
  function call elimination can make a big difference.
  
  This commit inlines the relatively trivial changegroup.readexactly()
  method inside the loop.
  
  The results with `hg perfbundleread` on a bundle of the Firefox repo
  speak for themselves:
  
  ! read(8k)
  ! wall 0.679730 comb 0.680000 user 0.140000 sys 0.540000 (best of 15)
  ! read(16k)
  ! wall 0.577228 comb 0.570000 user 0.080000 sys 0.490000 (best of 17)
  ! read(32k)
  ! wall 0.516060 comb 0.520000 user 0.040000 sys 0.480000 (best of 20)
  ! read(128k)
  ! wall 0.496378 comb 0.490000 user 0.010000 sys 0.480000 (best of 20)
  ! bundle2 iterparts()
  ! wall 3.460903 comb 3.460000 user 2.760000 sys 0.700000 (best of 3)
  ! wall 3.056811 comb 3.050000 user 2.340000 sys 0.710000 (best of 4)
  ! bundle2 iterparts() seekable
  ! wall 4.312722 comb 4.310000 user 3.480000 sys 0.830000 (best of 3)
  ! wall 4.007676 comb 4.000000 user 3.170000 sys 0.830000 (best of 3)
  ! bundle2 part seek()
  ! wall 6.754764 comb 6.740000 user 3.970000 sys 2.770000 (best of 3)
  ! wall 6.267110 comb 6.250000 user 3.480000 sys 2.770000 (best of 3)
  ! bundle2 part read(8k)
  ! wall 3.668004 comb 3.660000 user 2.960000 sys 0.700000 (best of 3)
  ! wall 3.404164 comb 3.400000 user 2.650000 sys 0.750000 (best of 3)
  ! bundle2 part read(16k)
  ! wall 3.489196 comb 3.480000 user 2.750000 sys 0.730000 (best of 3)
  ! wall 3.197972 comb 3.200000 user 2.490000 sys 0.710000 (best of 4)
  ! bundle2 part read(32k)
  ! wall 3.388569 comb 3.380000 user 2.640000 sys 0.740000 (best of 3)
  ! wall 3.060557 comb 3.060000 user 2.340000 sys 0.720000 (best of 4)
  ! bundle2 part read(128k)
  ! wall 3.276415 comb 3.270000 user 2.560000 sys 0.710000 (best of 4)
  ! wall 2.952209 comb 2.950000 user 2.230000 sys 0.720000 (best of 4)

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1392

AFFECTED FILES
  mercurial/bundle2.py

CHANGE DETAILS

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -1198,22 +1198,36 @@
 
     headersize = struct.calcsize(_fpayloadsize)
     readexactly = changegroup.readexactly
+    read = fh.read
 
     chunksize = _unpack(_fpayloadsize, readexactly(fh, headersize))[0]
     indebug(ui, 'payload chunk size: %i' % chunksize)
 
+    # changegroup.readexactly() is inlined below for performance.
     while chunksize:
         if chunksize >= 0:
-            yield readexactly(fh, chunksize)
+            s = read(chunksize)
+            if len(s) < chunksize:
+                raise error.Abort(_('stream ended unexpectedly '
+                                    ' (got %d bytes, expected %d)') %
+                                  (len(s), chunksize))
+
+            yield s
         elif chunksize == flaginterrupt:
             # Interrupt "signal" detected. The regular stream is interrupted
             # and a bundle2 part follows. Consume it.
             interrupthandler(ui, fh)()
         else:
             raise error.BundleValueError(
                 'negative payload chunk size: %s' % chunksize)
 
-        chunksize = _unpack(_fpayloadsize, readexactly(fh, headersize))[0]
+        s = read(headersize)
+        if len(s) < headersize:
+            raise error.Abort(_('stream ended unexpectedly '
+                                ' (got %d bytes, expected %d)') %
+                              (len(s), chunksize))
+
+        chunksize = _unpack(_fpayloadsize, s)[0]
 
         # indebug() inlined for performance.
         if dolog:



To: indygreg, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list