Mercurial > hg
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 |