comparison mercurial/util.py @ 17962:4c29668ca316 stable

util: make chunkbuffer non-quadratic on Windows The old str-based += collector performed very nicely on Linux, but turns out to be quadratically expensive on Windows, causing chunkbuffer to dominate in profiles. This list-based version has been measured to significantly improve performance with large chunks on Windows, with negligible overall overhead on Linux (though microbenchmarks show it to be about 50% slower). This may increase memory overhead where += didn't behave quadratically. If we want to gather up 1G of data to join, we temporarily have 1G in our list and 1G in our string.
author Matt Mackall <mpm@selenic.com>
date Mon, 26 Nov 2012 15:42:52 -0600
parents 9ee25d7b1aed
children 98c867ac1330
comparison
equal deleted inserted replaced
17961:b0affcb67cba 17962:4c29668ca316
897 897
898 def read(self, l): 898 def read(self, l):
899 """Read L bytes of data from the iterator of chunks of data. 899 """Read L bytes of data from the iterator of chunks of data.
900 Returns less than L bytes if the iterator runs dry.""" 900 Returns less than L bytes if the iterator runs dry."""
901 left = l 901 left = l
902 buf = '' 902 buf = []
903 queue = self._queue 903 queue = self._queue
904 while left > 0: 904 while left > 0:
905 # refill the queue 905 # refill the queue
906 if not queue: 906 if not queue:
907 target = 2**18 907 target = 2**18
915 915
916 chunk = queue.popleft() 916 chunk = queue.popleft()
917 left -= len(chunk) 917 left -= len(chunk)
918 if left < 0: 918 if left < 0:
919 queue.appendleft(chunk[left:]) 919 queue.appendleft(chunk[left:])
920 buf += chunk[:left] 920 buf.append(chunk[:left])
921 else: 921 else:
922 buf += chunk 922 buf.append(chunk)
923 923
924 return buf 924 return ''.join(buf)
925 925
926 def filechunkiter(f, size=65536, limit=None): 926 def filechunkiter(f, size=65536, limit=None):
927 """Create a generator that produces the data in the file size 927 """Create a generator that produces the data in the file size
928 (default 65536) bytes at a time, up to optional limit (default is 928 (default 65536) bytes at a time, up to optional limit (default is
929 to read all data). Chunks may be less than size bytes if the 929 to read all data). Chunks may be less than size bytes if the