# HG changeset patch # User Yuya Nishihara # Date 1492920383 -32400 # Node ID 853574db5b12209f6b2e98d12cf5af83670852fe # Parent f4433f2713d08a21ef1b595818e9f85a3271b557 encoding: add fast path of from/tolocal() for ASCII strings This is micro optimization, but seems not bad since to/fromlocal() is called lots of times and isasciistr() is cheap and simple. We boldly assume that any non-ASCII characters have at least one 8-bit byte. This isn't true for some email character sets (e.g. ISO-2022-JP and UTF-7), but I believe no such encodings are used as a platform default. Shift_JIS, a major crap, is okay as it should have a leading byte in 0x80-0xff range. (with mercurial repo) $ export HGRCPATH=/dev/null HGPLAIN= $ hg log --time --config experimental.stabilization=all > /dev/null (original) time: real 7.460 secs (user 7.420+0.000 sys 0.030+0.000) time: real 7.670 secs (user 7.590+0.000 sys 0.080+0.000) time: real 7.560 secs (user 7.510+0.000 sys 0.040+0.000) (this patch) time: real 7.340 secs (user 7.260+0.000 sys 0.060+0.000) time: real 7.260 secs (user 7.210+0.000 sys 0.030+0.000) time: real 7.310 secs (user 7.260+0.000 sys 0.060+0.000) diff -r f4433f2713d0 -r 853574db5b12 mercurial/encoding.py --- a/mercurial/encoding.py Sun Apr 23 12:59:42 2017 +0900 +++ b/mercurial/encoding.py Sun Apr 23 13:06:23 2017 +0900 @@ -128,6 +128,9 @@ 'foo: \\xc3\\xa4' """ + if isasciistr(s): + return s + try: try: # make sure string is actually stored in UTF-8 @@ -170,6 +173,8 @@ # can we do a lossless round-trip? if isinstance(s, localstr): return s._utf8 + if isasciistr(s): + return s try: u = s.decode(_sysstr(encoding), _sysstr(encodingmode)) diff -r f4433f2713d0 -r 853574db5b12 tests/test-encoding-func.py --- a/tests/test-encoding-func.py Sun Apr 23 12:59:42 2017 +0900 +++ b/tests/test-encoding-func.py Sun Apr 23 13:06:23 2017 +0900 @@ -28,6 +28,12 @@ t[i] |= 0x80 self.assertFalse(encoding.isasciistr(bytes(t))) +class LocalEncodingTest(unittest.TestCase): + def testasciifastpath(self): + s = b'\0' * 100 + self.assertTrue(s is encoding.tolocal(s)) + self.assertTrue(s is encoding.fromlocal(s)) + if __name__ == '__main__': import silenttestrunner silenttestrunner.main(__name__)