diff options
Diffstat (limited to 'xdelta3/xdelta3-regtest.py')
-rwxr-xr-x | xdelta3/xdelta3-regtest.py | 195 |
1 files changed, 152 insertions, 43 deletions
diff --git a/xdelta3/xdelta3-regtest.py b/xdelta3/xdelta3-regtest.py index 8cdacac..764eed4 100755 --- a/xdelta3/xdelta3-regtest.py +++ b/xdelta3/xdelta3-regtest.py | |||
@@ -1,6 +1,6 @@ | |||
1 | #!/usr/bin/python2.4 | 1 | #!/usr/bin/python2.4 |
2 | # xdelta 3 - delta compression tools and library | 2 | # xdelta 3 - delta compression tools and library |
3 | # Copyright (C) 2003 and onward. Joshua P. MacDonald | 3 | # Copyright (C) 2003, 2006, 2007. Joshua P. MacDonald |
4 | # | 4 | # |
5 | # This program is free software; you can redistribute it and/or modify | 5 | # This program is free software; you can redistribute it and/or modify |
6 | # it under the terms of the GNU General Public License as published by | 6 | # it under the terms of the GNU General Public License as published by |
@@ -618,50 +618,158 @@ def BigFileRun(f1, f2): | |||
618 | #end | 618 | #end |
619 | return 1 | 619 | return 1 |
620 | 620 | ||
621 | def RandomBigRun(f1, f2): | 621 | class RandomTestResult: |
622 | 622 | def __init__(self, config, runtime, compsize): | |
623 | input_ranges = [ | 623 | self.myconfig = config |
624 | (7, 20, 'large_look'), | 624 | self.runtime = runtime |
625 | (1, 30, 'large_step'), | 625 | self.compsize = compsize |
626 | (4, 5, 'small_look'), | 626 | #end |
627 | (1, 32, 'small_chain'), | ||
628 | (1, 16, 'small_lchain'), | ||
629 | (0, 1, 'ssmatch'), | ||
630 | (0, 1, 'trylazy'), | ||
631 | (1, 128, 'max_lazy'), | ||
632 | (1, 256, 'long_enough'), | ||
633 | (0, 1, 'promote'), | ||
634 | ] | ||
635 | 627 | ||
636 | config = [] | 628 | def __str__(self): |
637 | rand = random.Random() | 629 | return '%.4f %d [%s]' % (self.time(), self.size(), ' '.join([str(x) for x in self.config()])) |
638 | map = {} | 630 | #end |
639 | 631 | ||
640 | for input in input_ranges: | 632 | def time(self): |
641 | x = rand.randrange(input[0], input[1] + 1) | 633 | return self.runtime |
642 | config.append(x) | ||
643 | map[input[2]] = x | ||
644 | #end | 634 | #end |
645 | 635 | ||
646 | if map['small_chain'] < map['small_lchain']: | 636 | def size(self): |
647 | return | 637 | return self.compsize |
638 | #end | ||
639 | |||
640 | def config(self): | ||
641 | return self.myconfig | ||
642 | #end | ||
643 | #end | ||
644 | |||
645 | def PosInAlist(l, e): | ||
646 | for i in range(len(l)): | ||
647 | if l[i][1] == e: | ||
648 | return i; | ||
649 | #end | ||
650 | #end | ||
651 | return -1 | ||
652 | #end | ||
653 | |||
654 | # How many results per round | ||
655 | MAX_RESULTS = 20 | ||
656 | |||
657 | class RandomTester: | ||
658 | def __init__(self): | ||
659 | self.results = [] | ||
660 | #end | ||
661 | |||
662 | def HasEnoughResults(self): | ||
663 | return len(self.results) >= MAX_RESULTS | ||
664 | #end | ||
665 | |||
666 | def RandomBigRun(self, f1, f2): | ||
667 | |||
668 | input_ranges = [ | ||
669 | (7, 9, 12, 'large_look'), | ||
670 | (1, 9, 17, 'large_step'), | ||
671 | (4, 4, 4, 'small_look'), # Note: disabled | ||
672 | (1, 10, 100, 'small_chain'), | ||
673 | (1, 5, 50, 'small_lchain'), | ||
674 | (0, 0, 0, 'ssmatch'), # Note: disabled | ||
675 | (1, 1, 1, 'trylazy'), # Note: enabled | ||
676 | (1, 128, 1024, 'max_lazy'), | ||
677 | (1, 256, 2048, 'long_enough'), | ||
678 | (0, 0, 0, 'promote'), # Note: disabled | ||
679 | ] | ||
680 | |||
681 | config = [] | ||
682 | rand = random.Random() | ||
683 | map = {} | ||
684 | |||
685 | for input in input_ranges: | ||
686 | minv = input[0] | ||
687 | mean = input[1] | ||
688 | maxv = input[2] | ||
689 | name = input[3] | ||
690 | if minv == maxv: | ||
691 | val = minv | ||
692 | else: | ||
693 | val = -1 | ||
694 | while val < minv or val > maxv: | ||
695 | val = int(rand.expovariate(1.0 / mean)) | ||
696 | #end | ||
697 | #end | ||
698 | |||
699 | config.append(val) | ||
700 | map[name] = val | ||
701 | #end | ||
702 | |||
703 | if map['small_chain'] < map['small_lchain']: | ||
704 | return | ||
705 | |||
706 | if map['large_look'] < map['small_look']: | ||
707 | return | ||
648 | 708 | ||
649 | if map['large_look'] < map['small_look']: | 709 | strs = [str(x) for x in config] |
710 | |||
711 | runner = Xdelta3Pair() | ||
712 | runner.extra = ['-I', '0', '-D', '-C', ','.join(strs)] | ||
713 | result = TimeRun(runner.Runner(f1, 1, f2, 2)) | ||
714 | |||
715 | print 'config %s dsize %d time %.7f in %u trials' % \ | ||
716 | (' '.join(strs), | ||
717 | result.r1.dsize, | ||
718 | result.time.mean, | ||
719 | result.trials) | ||
720 | |||
721 | self.results.append(RandomTestResult(config, | ||
722 | result.time.mean, | ||
723 | result.r1.dsize)) | ||
650 | return | 724 | return |
651 | 725 | #end | |
652 | strs = [str(x) for x in config] | ||
653 | 726 | ||
654 | runner = Xdelta3Pair() | 727 | def ScoreTests(self): |
655 | runner.extra = ['-I', '0', '-D', '-C', ','.join(strs)] | 728 | mint = float(min([test.time() for test in self.results])) |
656 | result = TimeRun(runner.Runner(f1, 1, f2, 2)) | 729 | maxt = float(max([test.time() for test in self.results])) |
730 | mins = float(min([test.size() for test in self.results])) | ||
731 | maxs = float(max([test.size() for test in self.results])) | ||
732 | |||
733 | scored = [] | ||
734 | timed = [] | ||
735 | sized = [] | ||
736 | |||
737 | for test in self.results: | ||
738 | ntime = (test.time()) / float(maxt) | ||
739 | nsize = (test.size()) / float(maxs) | ||
740 | score = math.sqrt((maxs / mins) * ntime * ntime + | ||
741 | (maxt / mint) * nsize * nsize) | ||
742 | scored.append((score, test)) | ||
743 | timed.append((test.time(), test, score)) | ||
744 | sized.append((test.size(), test, score)) | ||
745 | #end | ||
746 | scored.sort() | ||
747 | timed.sort() | ||
748 | sized.sort() | ||
749 | for (score, test) in scored: | ||
750 | spos = PosInAlist(sized, test) | ||
751 | tpos = PosInAlist(timed, test) | ||
752 | print 'Score %f: %s (%d, %d)' % (score, test, spos, tpos) | ||
753 | #end | ||
754 | |||
755 | scored = scored[0:MAX_RESULTS/2] | ||
756 | sized = sized[0:MAX_RESULTS/2] | ||
757 | timed = timed[0:MAX_RESULTS/2] | ||
758 | |||
759 | for (size, test, score) in sized: | ||
760 | print 'Size: %s (%f)' % (test, score) | ||
761 | #end | ||
657 | 762 | ||
658 | print 'config %s dsize %d time %.7f in %u trials' % \ | 763 | for (time, test, score) in timed: |
659 | (' '.join(strs), | 764 | print 'Time: %s (%f)' % (test, score) |
660 | result.r1.dsize, | 765 | #end |
661 | result.time.mean, | ||
662 | result.trials) | ||
663 | 766 | ||
664 | return (config, result.r1.dsize, result.time.mean) | 767 | self.results = [] |
768 | for (score, test) in scored: | ||
769 | self.results.append(test) | ||
770 | #end | ||
771 | #end | ||
772 | #end | ||
665 | 773 | ||
666 | def RunSpeed(): | 774 | def RunSpeed(): |
667 | for L in Decimals(MAX_RUN): | 775 | for L in Decimals(MAX_RUN): |
@@ -674,17 +782,18 @@ def RunSpeed(): | |||
674 | if __name__ == "__main__": | 782 | if __name__ == "__main__": |
675 | try: | 783 | try: |
676 | os.mkdir(TMPDIR) | 784 | os.mkdir(TMPDIR) |
677 | rcsf = Test() | 785 | #rcsf = Test() |
678 | #rcsf.PairsByDate(Xdelta3Pair()) | 786 | #rcsf.PairsByDate(Xdelta3Pair()) |
679 | #RunSpeed() | 787 | #RunSpeed() |
788 | #f1, f2 = MakeBigFiles(rcsf) | ||
789 | f1 = '/tmp/big.1' | ||
790 | f2 = '/tmp/big.2' | ||
791 | test = RandomTester() | ||
680 | while 1: | 792 | while 1: |
681 | try: | 793 | while not test.HasEnoughResults(): |
682 | f1, f2 = MakeBigFiles(rcsf) | 794 | test.RandomBigRun(f1, f2) |
683 | #RandomBigRun("/tmp/big.1", "/tmp/big.2") | ||
684 | BigFileRun(f1, f2) | ||
685 | except CommandError, e: | ||
686 | pass | ||
687 | #end | 795 | #end |
796 | test.ScoreTests() | ||
688 | #end | 797 | #end |
689 | except CommandError: | 798 | except CommandError: |
690 | pass | 799 | pass |