comparison contrib/sillybench.py @ 721:2180358c32c4

Move some files to contrib
author Dongsheng Song <dongsheng.song@gmail.com>
date Thu, 12 Mar 2009 15:40:40 +0800
parents sillybench/sillybench.py@b2b593eb56e7
children
comparison
equal deleted inserted replaced
720:1ef7708b3b7f 721:2180358c32c4
1 #!/usr/bin/python
2 #
3 # Silly benchmarking program, to give a vague idea of how fast a few
4 # tools are on a handful of common operations.
5 #
6 # Use a fairly big and real source tarball to test with: Firefox
7 # 2.0.0.3 (37622 files, 5374 directories, 343MB unpacked onto
8 # 4KB-blocksize ext3).
9
10 import csv
11 import os
12 import shutil
13 import sys
14 import tempfile
15 import time
16 import urllib2
17
18 url = 'ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/2.0.0.3/source/firefox-2.0.0.3-source.tar.bz2'
19
20 class CommandFailure(Exception):
21 pass
22
23 class rcs(object):
24 def __init__(self):
25 self.logfp = open(self.__class__.__name__ + '.csv', 'w')
26 self.csv = csv.writer(self.logfp)
27
28 def download(self):
29 name = url[url.rfind('/')+1:]
30 path = os.path.join(os.environ['HOME'], name)
31 if not os.path.isfile(path):
32 ofp = open(path + '.part', 'wb')
33 try:
34 ifp = urllib2.urlopen(url)
35 nbytes = ifp.info()['content-length']
36 sys.stdout.write('%s: %s bytes ' % (name, nbytes))
37 sys.stdout.flush()
38 while True:
39 data = ifp.read(131072)
40 if not data: break
41 sys.stdout.write('.')
42 sys.stdout.flush()
43 ofp.write(data)
44 del ofp
45 os.rename(path + '.part', path)
46 except:
47 if os.path.exists(path + '.part'):
48 os.unlink(path + '.part')
49 if os.path.exists(path):
50 os.unlink(path)
51 raise
52 return path
53
54 def run(self, args, mustsucceed=True):
55 ret = os.spawnvp(os.P_WAIT, args[0], args)
56 if ret < 0:
57 msg = 'killed by signal %d' % (-ret)
58 if ret > 0:
59 msg = 'exited with status %d' % (ret)
60 if ret:
61 if mustsucceed:
62 raise CommandFailure('%s: %s' % (msg, ' '.join(args)))
63 print >> sys.stderr, 'WARNING: %s: %s' % (msg, ' '.join(args))
64
65 def time(self, *args, **kwargs):
66 start = time.time()
67 self.run(*args, **kwargs)
68 end = time.time()
69 return end - start
70
71 def logtime(self, name, elapsed, rest=[]):
72 self.log('time:' + name, '%.3f' % elapsed, rest)
73
74 def log(self, name, value, rest=[]):
75 item = (name, value, repr(rest))
76 print ' '.join(item)
77 self.csv.writerow(item)
78 self.logfp.flush()
79
80 def unpack(self):
81 tarball = self.download()
82 t = self.time(['tar', '-C', self.wdir, '-jxf', tarball])
83 self.logtime('internal:untar', t)
84 for name in os.listdir(os.path.join(self.wdir, 'mozilla')):
85 os.rename(os.path.join(self.wdir, 'mozilla', name),
86 os.path.join(self.wdir, name))
87
88 def cleanup(self):
89 pass
90
91 def add(self, paths):
92 pass
93
94 def commit(self, msg, paths):
95 pass
96
97 def status(self, path):
98 pass
99
100 def remove(self, path):
101 pass
102
103
104 class subversion(rcs):
105 def __init__(self, root):
106 rcs.__init__(self)
107 self.repo = os.path.join(root, 'repo')
108 self.wdir = os.path.join(root, 'wc')
109 create = self.time(['svnadmin', 'create', '--fs-type=fsfs', self.repo])
110 self.logtime('svn:create', create)
111 co = self.time(['svn', 'co', 'file://' + self.repo, self.wdir])
112 self.logtime('svn:co', co)
113 self.logtime('init', create + co)
114 os.chdir(self.wdir)
115
116 def dropmeta(self, names):
117 return [n for n in names if os.path.basename(n) != '.svn']
118
119 def add(self, paths):
120 t = self.time(['svn', 'add', '-q'] + paths)
121 self.logtime('add %r' % paths, t)
122
123 def commit(self, msg, paths=[]):
124 if paths:
125 t = self.time(['svn', 'ci', '-q', '-m', msg] + paths)
126 else:
127 t = self.time(['svn', 'ci', '-q', '-m', msg])
128 self.logtime('commit %r' % paths, t)
129
130
131 class mercurial(rcs):
132 def __init__(self, root):
133 rcs.__init__(self)
134 self.repo = os.path.join(root, 'repo')
135 self.wdir = self.repo
136 init = self.time(['hg', 'init', self.repo])
137 self.logtime('init', init)
138 os.chdir(self.wdir)
139
140 def dropmeta(self, names):
141 return [n for n in names if os.path.basename(n) != '.hg']
142
143 def add(self, paths):
144 t = self.time(['hg', 'add', '-q'] + paths)
145 self.logtime('add %r' % paths, t)
146
147 def commit(self, msg, paths=[]):
148 if paths:
149 t = self.time(['hg', 'ci', '-q', '-m', msg] + paths)
150 else:
151 t = self.time(['hg', 'ci', '-q', '-m', msg])
152 self.logtime('commit %r' % paths, t)
153
154 def benchmark(cls):
155 oldcwd = os.getcwd()
156 root = tempfile.mkdtemp(prefix='sillybench.')
157 try:
158 print 'root', root
159 inst = cls(root)
160 inst.unpack()
161 names = inst.dropmeta(os.listdir('.'))
162 dirs = [n for n in names if os.path.isdir(n)]
163 nondirs = [n for n in names if not os.path.isdir(n)]
164 dirs.sort(key=hash)
165 names.sort(key=hash)
166 for d in dirs[:len(dirs)/2]:
167 inst.add([d])
168 inst.commit('Add %r' % d, [d])
169 inst.add(dirs[len(dirs)/2:] + names)
170 inst.commit('Add remaining dirs and files')
171 finally:
172 print >> sys.stderr, '[cleaning up...]'
173 shutil.rmtree(root)
174 os.chdir(oldcwd)
175
176 benchmark(mercurial)
177 #benchmark(subversion)