isFloat: Without Exception-Handling
Mark McEahern
marklists at mceahern.com
Fri Sep 20 12:32:19 EDT 2002
For what it's worth, here's a slightly tweaked version of the test harness.
It shuffles the function list before testing and does multiple test runs and
then averages the results. I'm posting this mainly so that I can archive
this on this list without having to bother figuring out where to put it on
my own hard disk. <wink>
isFloatExcept comes out pretty consistently almost twice as fast as the
RE-based approach. Now, wouldn't I feel real dumb to find Python comes with
a builtin isfloat?
If not, are there other alternatives for doing this?
Easy come, easy go.
Cheers,
// m
#!/usr/bin/env python
import re
import random
import operator
from time import clock
# Compile up front.
floatPattern = re.compile(r"^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$")
def isFloatExcept(s):
try:
float(s)
return True
except (ValueError, TypeError), e:
return False
def isFloatRE(s):
floatRE = r"^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$"
return re.match(floatRE, str(s)) is not None
def isFloatRECompiled(s):
return floatPattern.match(str(s)) is not None
def time_it(fn, test_data, n):
time_in = clock()
for x in xrange(n):
for (s, expected) in test_data:
actual = fn(s)
assert actual == expected
time_out = clock()
return time_out - time_in
def show(fn, r, fastest):
avg = average(r)
ratio = (avg / fastest) * 100
print "%-20s %1.3f %2.f" % (fn.func_name, average(r), ratio)
def average(seq):
return reduce(operator.add, seq) / len(seq)
def test():
test_data = [(1.2, True),
(1, True),
(-1, True),
(1e+10, True),
("1e-10", True),
("banana", False),
("5j", False),
(4+0j, False),
(isFloatExcept, False),
(__import__, False),
(clock, False)]
test_runs = 10
n = 100
results = {}
functions = [isFloatExcept, isFloatRE, isFloatRECompiled]
for t in xrange(test_runs):
random.shuffle(functions)
for fn in functions:
r = time_it(fn, test_data, n)
results.setdefault(fn, [])
results[fn].append(r)
keys = results.keys()
keys.sort(lambda x, y: cmp(average(results[x]), average(results[y])))
fastest = average(results[keys[0]])
print "%-20s %s %s" % ("name", "clock", "cmp")
for fn in keys:
show(fn, results[fn], fastest)
if __name__ == "__main__":
test()
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: junk.py
URL: <http://mail.python.org/pipermail/python-list/attachments/20020920/9617ca91/attachment.ksh>
More information about the Python-list
mailing list