isFloat: Without Exception-Handling

Mark McEahern marklists at mceahern.com
Fri Sep 20 16:15:55 CEST 2002


[Magnus Lycka]
> Something like this perhaps:
>
> import re
>
> def isFloat(S):
>      floatRE = r"^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$"
>      return re.match(floatRE, str(S)) is not None
>
> I'm not sure it's faster though.

If you were going to run this lots of times, you might want to compile the
pattern.  Anyway, the exception based code is faster, by my testing (harness
at bottom):

       isFloatExcept 0.220
           isFloatRE 0.521
   isFloatRECompiled 0.400

Again, I wonder, why avoid the exception test?

Cheers,

// mark

Harness:

#!/usr/bin/env python

import re
from time import clock

# Compile up front.
floatPattern = re.compile(r"^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$")

def isFloatExcept(s):
    is_float = True
    try:
        float(s)
    except (ValueError, TypeError), e:
        is_float = False
    return is_float

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):
    print "%20s %1.3f" % (fn.func_name, r)

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)]
    n = 1000
    results = {}
    for fn in (isFloatExcept, isFloatRE, isFloatRECompiled):
        r = time_it(fn, test_data, n)
        results[fn] = r
    for fn in results:
        show(fn, results[fn])

if __name__ == "__main__":
    test()

-





More information about the Python-list mailing list