857 |
857 |
858 timer(d) |
858 timer(d) |
859 fm.end() |
859 fm.end() |
860 |
860 |
861 @command('perfrevlogchunks', revlogopts + formatteropts + |
861 @command('perfrevlogchunks', revlogopts + formatteropts + |
862 [('s', 'startrev', 0, 'revision to start at')], |
862 [('e', 'engines', '', 'compression engines to use'), |
|
863 ('s', 'startrev', 0, 'revision to start at')], |
863 '-c|-m|FILE') |
864 '-c|-m|FILE') |
864 def perfrevlogchunks(ui, repo, file_=None, startrev=0, **opts): |
865 def perfrevlogchunks(ui, repo, file_=None, engines=None, startrev=0, **opts): |
865 """Benchmark operations on revlog chunks. |
866 """Benchmark operations on revlog chunks. |
866 |
867 |
867 Logically, each revlog is a collection of fulltext revisions. However, |
868 Logically, each revlog is a collection of fulltext revisions. However, |
868 stored within each revlog are "chunks" of possibly compressed data. This |
869 stored within each revlog are "chunks" of possibly compressed data. This |
869 data needs to be read and decompressed or compressed and written. |
870 data needs to be read and decompressed or compressed and written. |
872 chunks in a revlog. It effectively isolates I/O and compression performance. |
873 chunks in a revlog. It effectively isolates I/O and compression performance. |
873 For measurements of higher-level operations like resolving revisions, |
874 For measurements of higher-level operations like resolving revisions, |
874 see ``perfrevlog`` and ``perfrevlogrevision``. |
875 see ``perfrevlog`` and ``perfrevlogrevision``. |
875 """ |
876 """ |
876 rl = cmdutil.openrevlog(repo, 'perfrevlogchunks', file_, opts) |
877 rl = cmdutil.openrevlog(repo, 'perfrevlogchunks', file_, opts) |
|
878 |
|
879 # Verify engines argument. |
|
880 if engines: |
|
881 engines = set(e.strip() for e in engines.split(',')) |
|
882 for engine in engines: |
|
883 try: |
|
884 util.compressionengines[engine] |
|
885 except KeyError: |
|
886 raise error.Abort('unknown compression engine: %s' % engine) |
|
887 else: |
|
888 engines = [] |
|
889 for e in util.compengines: |
|
890 engine = util.compengines[e] |
|
891 try: |
|
892 if engine.available(): |
|
893 engine.revlogcompressor().compress('dummy') |
|
894 engines.append(e) |
|
895 except NotImplementedError: |
|
896 pass |
|
897 |
877 revs = list(rl.revs(startrev, len(rl) - 1)) |
898 revs = list(rl.revs(startrev, len(rl) - 1)) |
878 |
899 |
879 def rlfh(rl): |
900 def rlfh(rl): |
880 if rl._inline: |
901 if rl._inline: |
881 return getsvfs(repo)(rl.indexfile) |
902 return getsvfs(repo)(rl.indexfile) |
914 rl.clearcaches() |
935 rl.clearcaches() |
915 fh = rlfh(rl) |
936 fh = rlfh(rl) |
916 # Save chunks as a side-effect. |
937 # Save chunks as a side-effect. |
917 chunks[0] = rl._chunks(revs, df=fh) |
938 chunks[0] = rl._chunks(revs, df=fh) |
918 |
939 |
919 def docompress(): |
940 def docompress(compressor): |
920 rl.clearcaches() |
941 rl.clearcaches() |
921 for chunk in chunks[0]: |
942 |
922 rl.compress(chunk) |
943 try: |
|
944 # Swap in the requested compression engine. |
|
945 oldcompressor = rl._compressor |
|
946 rl._compressor = compressor |
|
947 for chunk in chunks[0]: |
|
948 rl.compress(chunk) |
|
949 finally: |
|
950 rl._compressor = oldcompressor |
923 |
951 |
924 benches = [ |
952 benches = [ |
925 (lambda: doread(), 'read'), |
953 (lambda: doread(), 'read'), |
926 (lambda: doreadcachedfh(), 'read w/ reused fd'), |
954 (lambda: doreadcachedfh(), 'read w/ reused fd'), |
927 (lambda: doreadbatch(), 'read batch'), |
955 (lambda: doreadbatch(), 'read batch'), |
928 (lambda: doreadbatchcachedfh(), 'read batch w/ reused fd'), |
956 (lambda: doreadbatchcachedfh(), 'read batch w/ reused fd'), |
929 (lambda: dochunk(), 'chunk'), |
957 (lambda: dochunk(), 'chunk'), |
930 (lambda: dochunkbatch(), 'chunk batch'), |
958 (lambda: dochunkbatch(), 'chunk batch'), |
931 (lambda: docompress(), 'compress'), |
|
932 ] |
959 ] |
|
960 |
|
961 for engine in sorted(engines): |
|
962 compressor = util.compengines[engine].revlogcompressor() |
|
963 benches.append((functools.partial(docompress, compressor), |
|
964 'compress w/ %s' % engine)) |
933 |
965 |
934 for fn, title in benches: |
966 for fn, title in benches: |
935 timer, fm = gettimer(ui, opts) |
967 timer, fm = gettimer(ui, opts) |
936 timer(fn, title=title) |
968 timer(fn, title=title) |
937 fm.end() |
969 fm.end() |