Edgewall Software

source: trunk/examples/bench/xpath.py

Last change on this file was 1025, checked in by cmlenz, 15 years ago

Merged soc2008-xpath branch back into trunk.

File size: 5.5 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# Copyright (C) 2006-2008 Edgewall Software
4# All rights reserved.
5#
6# This software is licensed as described in the file COPYING, which
7# you should have received as part of this distribution. The terms
8# are also available at http://genshi.edgewall.org/wiki/License.
9#
10# This software consists of voluntary contributions made by many
11# individuals. For the exact contribution history, see the revision
12# history and logs, available at http://genshi.edgewall.org/log/.
13
14
15try:
16    from os import times
17    def time_func():
18        tup = times()
19        #just user time
20        return tup[0] # + tup[1]
21except ImportError:
22    from time import time as time_func
23
24from genshi.core import START, END
25from genshi.path import Path
26from genshi.input import XML
27
28def benchmark(f, acurate_time=1):
29    """Checks how much time does function f work. It runs it as
30    many times as needed for avoiding inaccuracy"""
31
32    runs = 1
33    while True:
34        start_time = time_func()
35        for _ in xrange(runs):
36            f()
37        dt = time_func() - start_time
38        if dt >= acurate_time:
39            break
40        runs *= 2
41    return dt / runs
42
43def spell(t):
44    """Returns spelled representation of time"""
45    units = [(0.000001, 'microsecond', 'microseconds'),
46             (0.001, 'milisecond', 'miliseconds'),
47             (1, 'second', 'seconds'),
48             (60, 'minute', 'minutes'),
49             (60*60, 'hour', 'hours'),
50            ]
51    i = 0
52    at = abs(t)
53    while i + 1 < len(units) and at >= units[i + 1][0]:
54        i += 1
55    t /= units[i][0]
56    if t >= 2:
57        name = units[i][2]
58    else:
59        name = units[i][1]
60    return "%f %s"%(t, name)
61
62def test_paths_in_streams(exprs, streams, test_strategies=False):
63    for expr in exprs:
64        print "Testing path %r" % expr
65        for stream, sname in streams:
66            print '\tRunning on "%s" example:' % sname
67
68            path = Path(expr)
69            def f():
70                for e in path.select(stream):
71                    pass
72            t = spell(benchmark(f))
73            print "\t\tselect:\t\t%s" % t
74
75            def f():
76                path = Path(expr)
77                for e in path.select(stream):
78                    pass
79            t = spell(benchmark(f))
80            print "\t\tinit + select:\t%s" % t
81
82            if test_strategies and len(path.paths) == 1:
83                from genshi.path import GenericStrategy, SingleStepStrategy, \
84                                        SimplePathStrategy
85                from genshi.tests.path import FakePath
86                strategies = (GenericStrategy, SingleStepStrategy,
87                              SimplePathStrategy)
88                for strategy in strategies:
89                    if not strategy.supports(path.paths[0]):
90                        continue
91                    print "\t\t%s Strategy"%strategy.__name__
92                    fp = FakePath(strategy(path.paths[0]))
93                    def f():
94                        for e in fp.select(stream):
95                            pass
96                    t = spell(benchmark(f))
97                    print "\t\t\tselect:\t\t%s"%t
98
99
100def test_documents(test_strategies=False):
101    streams = []
102
103    s = XML("""\
104<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl" xmlns:py="http://genshi.edgewall.org/" py:strip="" lang="en">
105    <head>
106        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
107        <title>Foo</title>
108    </head>
109    <body>
110        <h1>Hello</h1>
111    </body>
112</html>
113""")
114    streams.append((s, "small document"))
115
116    s = XML("""\
117<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl" xmlns:py="http://genshi.edgewall.org/" py:strip="" lang="en">
118    <head>
119        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
120        <title>Foo</title>
121    </head>
122    <body>
123        <h1>Hello</h1>
124        <div id="splash">
125            <ul>
126                <li><a class="b1" href="http://genshi.edgewall.org/">
127                        <strong>Genshi</strong>
128                        Python toolkit for generating output for the web</a></li>
129                <li><a class="b2" href="http://babel.edgewall.org/">
130                        <strong>Babel</strong>
131                        Python library for I18n/L10n in web applications</a></li>
132                <li><a class="b3" href="http://bitten.edgewall.org/">
133                        <strong>Bitten</strong>
134                        Continuous integration plugin for Trac</a></li>
135                <li><a class="b4" href="http://posterity.edgewall.org/">
136                        <strong>Posterity</strong>
137                        Web-based email system</a></li>
138            </ul>
139            <div id="trac-splash">
140                <a href="http://trac.edgewall.org/">
141                    <strong>Trac</strong> Web-based lightweight project management
142                    system
143                </a>
144            </div>
145        </div>
146    </body>
147</html>
148""")
149    streams.append((s, "big document"))
150
151    paths = [
152        '.',
153        '*|text()',
154        'html',
155        'html[@lang="en"]',
156        'html/body/h1/text()',
157        'html/body/div/a/@href',
158        'html/body/div[@id="splash"]/a[@class="b4"]/strong/text()',
159        'descendant-or-self::text()',
160        'descendant-or-self::h1/text()',
161    ]
162    test_paths_in_streams(paths, streams, test_strategies)
163
164if __name__ == '__main__':
165    from sys import argv
166    if "--strategies" in argv:
167        test_strategies = True
168    else:
169        test_strategies = False
170    test_documents(test_strategies)
Note: See TracBrowser for help on using the repository browser.