hgbook

diff sillybench/sillybench.py @ 271:8627f718517a

Fix typo "paptches"
author Max Vozeler <max@nusquama.org>
date Mon Sep 10 19:38:41 2007 +0200 (2007-09-10)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/sillybench/sillybench.py	Mon Sep 10 19:38:41 2007 +0200
     1.3 @@ -0,0 +1,177 @@
     1.4 +#!/usr/bin/python
     1.5 +#
     1.6 +# Silly benchmarking program, to give a vague idea of how fast a few
     1.7 +# tools are on a handful of common operations.
     1.8 +#
     1.9 +# Use a fairly big and real source tarball to test with: Firefox
    1.10 +# 2.0.0.3 (37622 files, 5374 directories, 343MB unpacked onto
    1.11 +# 4KB-blocksize ext3).
    1.12 +
    1.13 +import csv
    1.14 +import os
    1.15 +import shutil
    1.16 +import sys
    1.17 +import tempfile
    1.18 +import time
    1.19 +import urllib2
    1.20 +
    1.21 +url = 'ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/2.0.0.3/source/firefox-2.0.0.3-source.tar.bz2'
    1.22 +
    1.23 +class CommandFailure(Exception):
    1.24 +    pass
    1.25 +
    1.26 +class rcs(object):
    1.27 +    def __init__(self):
    1.28 +        self.logfp = open(self.__class__.__name__ + '.csv', 'w')
    1.29 +        self.csv = csv.writer(self.logfp)
    1.30 +
    1.31 +    def download(self):
    1.32 +        name = url[url.rfind('/')+1:]
    1.33 +        path = os.path.join(os.environ['HOME'], name)
    1.34 +        if not os.path.isfile(path):
    1.35 +            ofp = open(path + '.part', 'wb')
    1.36 +            try:
    1.37 +                ifp = urllib2.urlopen(url)
    1.38 +                nbytes = ifp.info()['content-length']
    1.39 +                sys.stdout.write('%s: %s bytes ' % (name, nbytes))
    1.40 +                sys.stdout.flush()
    1.41 +                while True:
    1.42 +                    data = ifp.read(131072)
    1.43 +                    if not data: break
    1.44 +                    sys.stdout.write('.')
    1.45 +                    sys.stdout.flush()
    1.46 +                    ofp.write(data)
    1.47 +                del ofp
    1.48 +                os.rename(path + '.part', path)
    1.49 +            except:
    1.50 +                if os.path.exists(path + '.part'):
    1.51 +                    os.unlink(path + '.part')
    1.52 +                if os.path.exists(path):
    1.53 +                    os.unlink(path)
    1.54 +                raise
    1.55 +        return path
    1.56 +
    1.57 +    def run(self, args, mustsucceed=True):
    1.58 +        ret = os.spawnvp(os.P_WAIT, args[0], args)
    1.59 +        if ret < 0:
    1.60 +            msg = 'killed by signal %d' % (-ret)
    1.61 +        if ret > 0:
    1.62 +            msg = 'exited with status %d' % (ret)
    1.63 +        if ret:
    1.64 +            if mustsucceed:
    1.65 +                raise CommandFailure('%s: %s' % (msg, ' '.join(args)))
    1.66 +            print >> sys.stderr, 'WARNING: %s: %s' % (msg, ' '.join(args))
    1.67 +
    1.68 +    def time(self, *args, **kwargs):
    1.69 +        start = time.time()
    1.70 +        self.run(*args, **kwargs)
    1.71 +        end = time.time()
    1.72 +        return end - start
    1.73 +        
    1.74 +    def logtime(self, name, elapsed, rest=[]):
    1.75 +        self.log('time:' + name, '%.3f' % elapsed, rest)
    1.76 +
    1.77 +    def log(self, name, value, rest=[]):
    1.78 +        item = (name, value, repr(rest))
    1.79 +        print ' '.join(item)
    1.80 +        self.csv.writerow(item)
    1.81 +        self.logfp.flush()
    1.82 +
    1.83 +    def unpack(self):
    1.84 +        tarball = self.download()
    1.85 +        t = self.time(['tar', '-C', self.wdir, '-jxf', tarball])
    1.86 +        self.logtime('internal:untar', t)
    1.87 +        for name in os.listdir(os.path.join(self.wdir, 'mozilla')):
    1.88 +            os.rename(os.path.join(self.wdir, 'mozilla', name),
    1.89 +                      os.path.join(self.wdir, name))
    1.90 +
    1.91 +    def cleanup(self):
    1.92 +        pass
    1.93 +
    1.94 +    def add(self, paths):
    1.95 +        pass
    1.96 +
    1.97 +    def commit(self, msg, paths):
    1.98 +        pass
    1.99 +
   1.100 +    def status(self, path):
   1.101 +        pass
   1.102 +
   1.103 +    def remove(self, path):
   1.104 +        pass
   1.105 +
   1.106 +
   1.107 +class subversion(rcs):
   1.108 +    def __init__(self, root):
   1.109 +        rcs.__init__(self)
   1.110 +        self.repo = os.path.join(root, 'repo')
   1.111 +        self.wdir = os.path.join(root, 'wc')
   1.112 +        create = self.time(['svnadmin', 'create', '--fs-type=fsfs', self.repo])
   1.113 +        self.logtime('svn:create', create)
   1.114 +        co = self.time(['svn', 'co', 'file://' + self.repo, self.wdir])
   1.115 +        self.logtime('svn:co', co)
   1.116 +        self.logtime('init', create + co)
   1.117 +        os.chdir(self.wdir)
   1.118 +
   1.119 +    def dropmeta(self, names):
   1.120 +        return [n for n in names if os.path.basename(n) != '.svn']
   1.121 +
   1.122 +    def add(self, paths):
   1.123 +        t = self.time(['svn', 'add', '-q'] + paths)
   1.124 +        self.logtime('add %r' % paths, t)
   1.125 +
   1.126 +    def commit(self, msg, paths=[]):
   1.127 +        if paths:
   1.128 +            t = self.time(['svn', 'ci', '-q', '-m', msg] + paths)
   1.129 +        else:
   1.130 +            t = self.time(['svn', 'ci', '-q', '-m', msg])
   1.131 +        self.logtime('commit %r' % paths, t)
   1.132 +
   1.133 +
   1.134 +class mercurial(rcs):
   1.135 +    def __init__(self, root):
   1.136 +        rcs.__init__(self)
   1.137 +        self.repo = os.path.join(root, 'repo')
   1.138 +        self.wdir = self.repo
   1.139 +        init = self.time(['hg', 'init', self.repo])
   1.140 +        self.logtime('init', init)
   1.141 +        os.chdir(self.wdir)
   1.142 +
   1.143 +    def dropmeta(self, names):
   1.144 +        return [n for n in names if os.path.basename(n) != '.hg']
   1.145 +
   1.146 +    def add(self, paths):
   1.147 +        t = self.time(['hg', 'add', '-q'] + paths)
   1.148 +        self.logtime('add %r' % paths, t)
   1.149 +
   1.150 +    def commit(self, msg, paths=[]):
   1.151 +        if paths:
   1.152 +            t = self.time(['hg', 'ci', '-q', '-m', msg] + paths)
   1.153 +        else:
   1.154 +            t = self.time(['hg', 'ci', '-q', '-m', msg])
   1.155 +        self.logtime('commit %r' % paths, t)
   1.156 +
   1.157 +def benchmark(cls):
   1.158 +    oldcwd = os.getcwd()
   1.159 +    root = tempfile.mkdtemp(prefix='sillybench.')
   1.160 +    try:
   1.161 +        print 'root', root
   1.162 +        inst = cls(root)
   1.163 +        inst.unpack()
   1.164 +        names = inst.dropmeta(os.listdir('.'))
   1.165 +        dirs = [n for n in names if os.path.isdir(n)]
   1.166 +        nondirs = [n for n in names if not os.path.isdir(n)]
   1.167 +        dirs.sort(key=hash)
   1.168 +        names.sort(key=hash)
   1.169 +        for d in dirs[:len(dirs)/2]:
   1.170 +            inst.add([d])
   1.171 +            inst.commit('Add %r' % d, [d])
   1.172 +        inst.add(dirs[len(dirs)/2:] + names)
   1.173 +        inst.commit('Add remaining dirs and files')
   1.174 +    finally:
   1.175 +        print >> sys.stderr, '[cleaning up...]'
   1.176 +        shutil.rmtree(root)
   1.177 +        os.chdir(oldcwd)
   1.178 +
   1.179 +benchmark(mercurial)
   1.180 +#benchmark(subversion)