perf: add threading capability to perfbdiff
Since we are releasing the GIL during diffing, it is interesting to see how a
thread pool would perform on diffing. We add a new `--threads` argument to
commands. Synchronizing the thread pool is a bit complex because we want to be
able to reuse it from one run to another.
On my computer (i7 with 4 cores + hyperthreading), I get the following data for
about 12000 revisions:
threads wall comb wall gain comb overhead
none 31.596715 31.59 0.00% 0.00%
1 31.621228 31.62 -0.08% 0.09%
2 16.406202 32.8 48.08% 3.83%
3 11.598334 34.76 63.29% 10.03%
4 9.205421 36.77 70.87% 16.40%
5 8.517604 42.51 73.04% 34.57%
6 7.94645 47.58 74.85% 50.62%
7 7.434972 51.92 76.47% 64.36%
8 7.070638 55.34 77.62% 75.18%
Compared to the feature disabled (threads=0), the overhead is negligible with
the threading code (threads=1), and the gain is already 48% with two threads.
$ cat > unix2mac.py <<EOF
> import sys
>
> for path in sys.argv[1:]:
> data = file(path, 'rb').read()
> data = data.replace('\n', '\r')
> file(path, 'wb').write(data)
> EOF
$ cat > print.py <<EOF
> import sys
> print(sys.stdin.read().replace('\n', '<LF>').replace('\r', '<CR>').replace('\0', '<NUL>'))
> EOF
$ hg init
$ echo '[hooks]' >> .hg/hgrc
$ echo 'pretxncommit.cr = python:hgext.win32text.forbidcr' >> .hg/hgrc
$ echo 'pretxnchangegroup.cr = python:hgext.win32text.forbidcr' >> .hg/hgrc
$ cat .hg/hgrc
[hooks]
pretxncommit.cr = python:hgext.win32text.forbidcr
pretxnchangegroup.cr = python:hgext.win32text.forbidcr
$ echo hello > f
$ hg add f
$ hg ci -m 1
$ $PYTHON unix2mac.py f
$ hg ci -m 2
attempt to commit or push text file(s) using CR line endings
in dea860dc51ec: f
transaction abort!
rollback completed
abort: pretxncommit.cr hook failed
[255]
$ hg cat f | $PYTHON print.py
hello<LF>
$ cat f | $PYTHON print.py
hello<CR>