~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/benchmarks/__init__.py

  • Committer: wang
  • Date: 2006-10-29 13:41:32 UTC
  • mto: (2104.4.1 wang_65714)
  • mto: This revision was merged to the branch mainline in revision 2109.
  • Revision ID: wang@ubuntu-20061029134132-3d7f4216f20c4aef
Replace python's difflib by patiencediff because the worst case 
performance is cubic for difflib and people commiting large data 
files are often hurt by this. The worst case performance of patience is 
quadratic. Fix bug 65714.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 by Canonical Ltd
 
1
# Copyright (C) 2006 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
 
18
17
"""Benchmark test suite for bzr."""
19
18
 
20
 
from bzrlib import bzrdir, plugin
 
19
from bzrlib import (
 
20
    bzrdir,
 
21
    plugin,
 
22
    )
 
23
import bzrlib.branch
21
24
from bzrlib.tests.TestUtil import TestLoader
22
25
from bzrlib.tests.blackbox import ExternalBase
23
26
 
24
27
 
25
28
class Benchmark(ExternalBase):
26
29
 
27
 
    def make_kernel_like_tree(self, url=None):
 
30
    def make_kernel_like_tree(self, url=None, root='.',
 
31
                              link_working=False):
28
32
        """Setup a temporary tree roughly like a kernel tree.
29
33
        
30
34
        :param url: Creat the kernel like tree as a lightweight checkout
31
35
        of a new branch created at url.
32
 
        """
33
 
        # a kernel tree has ~10000 and 500 directory, with most files around 
34
 
        # 3-4 levels deep. 
35
 
        # we simulate this by three levels of dirs named 0-7, givin 512 dirs,
36
 
        # and 20 files each.
37
 
        if url is not None:
38
 
            b = bzrdir.BzrDir.create_branch_convenience(url)
39
 
            d = bzrdir.BzrDir.create('.')
40
 
            bzrlib.branch.BranchReferenceFormat().initialize(d, b)
41
 
            d.create_workingtree()
42
 
        else:
43
 
            self.run_bzr('init')
44
 
        files = []
45
 
        for outer in range(8):
46
 
            files.append("%s/" % outer)
47
 
            for middle in range(8):
48
 
                files.append("%s/%s/" % (outer, middle))
49
 
                for inner in range(8):
50
 
                    prefix = "%s/%s/%s/" % (outer, middle, inner)
51
 
                    files.append(prefix)
52
 
                    files.extend([prefix + str(foo) for foo in range(20)])
53
 
        self.build_tree(files)
54
 
 
55
 
    def make_many_commit_tree(self, directory_name='.'):
 
36
        :param link_working: instead of creating a new copy of all files
 
37
            just hardlink the working tree. Tests must request this, because
 
38
            they must break links if they want to change the files
 
39
        """
 
40
        from bzrlib.benchmarks.tree_creator.kernel_like import (
 
41
            KernelLikeTreeCreator,
 
42
            )
 
43
        creator = KernelLikeTreeCreator(self, link_working=link_working,
 
44
                                        url=url)
 
45
        return creator.create(root=root)
 
46
 
 
47
    def make_kernel_like_added_tree(self, root='.',
 
48
                                    link_working=True,
 
49
                                    hot_cache=True):
 
50
        """Make a kernel like tree, with all files added
 
51
 
 
52
        :param root: Where to create the files
 
53
        :param link_working: Instead of copying all of the working tree
 
54
            files, just hardlink them to the cached files. Tests can unlink
 
55
            files that they will change.
 
56
        :param hot_cache: Run through the newly created tree and make sure
 
57
            the stat-cache is correct. The old way of creating a freshly
 
58
            added tree always had a hot cache.
 
59
        """
 
60
        from bzrlib.benchmarks.tree_creator.kernel_like import (
 
61
            KernelLikeAddedTreeCreator,
 
62
            )
 
63
        creator = KernelLikeAddedTreeCreator(self, link_working=link_working,
 
64
                                             hot_cache=hot_cache)
 
65
        return creator.create(root=root)
 
66
 
 
67
    def make_kernel_like_committed_tree(self, root='.',
 
68
                                    link_working=True,
 
69
                                    link_bzr=False,
 
70
                                    hot_cache=True):
 
71
        """Make a kernel like tree, with all files added and committed
 
72
 
 
73
        :param root: Where to create the files
 
74
        :param link_working: Instead of copying all of the working tree
 
75
            files, just hardlink them to the cached files. Tests can unlink
 
76
            files that they will change.
 
77
        :param link_bzr: Hardlink the .bzr directory. For readonly 
 
78
            operations this is safe, and shaves off a lot of setup time
 
79
        """
 
80
        from bzrlib.benchmarks.tree_creator.kernel_like import (
 
81
            KernelLikeCommittedTreeCreator,
 
82
            )
 
83
        creator = KernelLikeCommittedTreeCreator(self,
 
84
                                                 link_working=link_working,
 
85
                                                 link_bzr=link_bzr,
 
86
                                                 hot_cache=hot_cache)
 
87
        return creator.create(root=root)
 
88
 
 
89
    def make_kernel_like_inventory(self):
 
90
        """Create an inventory with the properties of a kernel-like tree
 
91
 
 
92
        This should be equivalent to a committed kernel like tree, not
 
93
        just a working tree.
 
94
        """
 
95
        from bzrlib.benchmarks.tree_creator.kernel_like import (
 
96
            KernelLikeInventoryCreator,
 
97
            )
 
98
        creator = KernelLikeInventoryCreator(self)
 
99
        return creator.create()
 
100
 
 
101
    def make_many_commit_tree(self, directory_name='.',
 
102
                              hardlink=False):
56
103
        """Create a tree with many commits.
57
104
        
58
 
        No files change are included.
 
105
        No file changes are included. Not hardlinking the working tree, 
 
106
        because there are no working tree files.
59
107
        """
60
 
        tree = bzrdir.BzrDir.create_standalone_workingtree(directory_name)
61
 
        tree.lock_write()
62
 
        tree.branch.lock_write()
63
 
        tree.branch.repository.lock_write()
64
 
        try:
65
 
            for i in xrange(1000):
66
 
                tree.commit('no-changes commit %d' % i)
67
 
        finally:
68
 
            try:
69
 
                try:
70
 
                    tree.branch.repository.unlock()
71
 
                finally:
72
 
                    tree.branch.unlock()
73
 
            finally:
74
 
                tree.unlock()
75
 
        return tree
 
108
        from bzrlib.benchmarks.tree_creator.simple_many_commit import (
 
109
            SimpleManyCommitTreeCreator,
 
110
            )
 
111
        creator = SimpleManyCommitTreeCreator(self, link_bzr=hardlink)
 
112
        return creator.create(root=directory_name)
76
113
 
77
 
    def make_heavily_merged_tree(self, directory_name='.'):
 
114
    def make_heavily_merged_tree(self, directory_name='.',
 
115
                                 hardlink=False):
78
116
        """Create a tree in which almost every commit is a merge.
79
117
       
80
 
        No files change are included.  This produces two trees, 
 
118
        No file changes are included.  This produces two trees, 
81
119
        one of which is returned.  Except for the first commit, every
82
120
        commit in its revision-history is a merge another commit in the other
83
 
        tree.
84
 
        """
85
 
        tree = bzrdir.BzrDir.create_standalone_workingtree(directory_name)
86
 
        tree.lock_write()
87
 
        try:
88
 
            tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
89
 
            tree2.lock_write()
90
 
            try:
91
 
                for i in xrange(250):
92
 
                    revision_id = tree.commit('no-changes commit %d-a' % i)
93
 
                    tree2.branch.fetch(tree.branch, revision_id)
94
 
                    tree2.set_pending_merges([revision_id])
95
 
                    revision_id = tree2.commit('no-changes commit %d-b' % i)
96
 
                    tree.branch.fetch(tree2.branch, revision_id)
97
 
                    tree.set_pending_merges([revision_id])
98
 
                tree.set_pending_merges([])
99
 
            finally:
100
 
                tree.unlock()
101
 
        finally:
102
 
            tree2.unlock()
103
 
        return tree
 
121
        tree.  Not hardlinking the working tree, because there are no working 
 
122
        tree files.
 
123
        """
 
124
        from bzrlib.benchmarks.tree_creator.heavily_merged import (
 
125
            HeavilyMergedTreeCreator,
 
126
            )
 
127
        creator = HeavilyMergedTreeCreator(self, link_bzr=hardlink)
 
128
        return creator.create(root=directory_name)
 
129
 
 
130
    def create_with_commits(self, num_files, num_commits, directory_name='.',
 
131
                            hardlink=False):
 
132
        """Create a tree with many files and many commits. Every commit changes
 
133
        exactly one file.
 
134
        
 
135
        :param num_files: number of files to be created
 
136
        :param num_commits: number of commits in the newly created tree
 
137
        """
 
138
        from bzrlib.benchmarks.tree_creator.many_commit import (
 
139
            ManyCommitTreeCreator,
 
140
            )
 
141
        creator = ManyCommitTreeCreator(self, link_bzr=hardlink,
 
142
                                        num_files=num_files,
 
143
                                        num_commits=num_commits)
 
144
        tree = creator.create(root=directory_name)
 
145
        files = ["%s/%s" % (directory_name, fn) for fn in creator.files]
 
146
        return tree, files
 
147
 
 
148
    def commit_some_revisions(self, tree, files, num_commits,
 
149
                              changes_per_commit):
 
150
        """Commit a specified number of revisions to some files in a tree,
 
151
        makeing a specified number of changes per commit.
 
152
 
 
153
        :param tree: The tree in which the changes happen.
 
154
        :param files: The list of files where changes should occur.
 
155
        :param num_commits: The number of commits
 
156
        :param changes_per_commit: The number of files that are touched in 
 
157
        each commit.
 
158
        """
 
159
        for j in range(num_commits):
 
160
            for i in range(changes_per_commit):
 
161
                fn = files[(i + j) % changes_per_commit]
 
162
                content = range(i) + [i, i, i, '']
 
163
                f = open(fn, "w")
 
164
                try:
 
165
                    f.write("\n".join([str(k) for k in content]))
 
166
                finally:
 
167
                    f.close()
 
168
            tree.commit("new revision")
104
169
 
105
170
 
106
171
def test_suite():
108
173
    testmod_names = [ \
109
174
                   'bzrlib.benchmarks.bench_add',
110
175
                   'bzrlib.benchmarks.bench_bench',
 
176
                   'bzrlib.benchmarks.bench_bundle',
 
177
                   'bzrlib.benchmarks.bench_cache_utf8',
111
178
                   'bzrlib.benchmarks.bench_checkout',
112
179
                   'bzrlib.benchmarks.bench_commit',
 
180
                   'bzrlib.benchmarks.bench_info',
113
181
                   'bzrlib.benchmarks.bench_inventory',
114
182
                   'bzrlib.benchmarks.bench_log',
115
183
                   'bzrlib.benchmarks.bench_osutils',
116
184
                   'bzrlib.benchmarks.bench_rocks',
 
185
                   'bzrlib.benchmarks.bench_startup',
117
186
                   'bzrlib.benchmarks.bench_status',
118
187
                   'bzrlib.benchmarks.bench_transform',
119
188
                   'bzrlib.benchmarks.bench_workingtree',
 
189
                   'bzrlib.benchmarks.bench_sftp',
 
190
                   'bzrlib.benchmarks.bench_xml',
120
191
                   ]
121
192
    suite = TestLoader().loadTestsFromModuleNames(testmod_names) 
122
193