Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simple example to test how much faster or slower it is to simply try and convert then catch an error vs. testing up front.
import datetime
import random
from typing import List
def main():
random.seed(172)
count = 1_000_000
data = build_data(count)
run_with_except(data)
run_with_test(data)
def build_data(count: int):
letters = "abcdefghijklmnopqrstuv"
numbers = list(range(1, 11))
combined = list(letters) + numbers
return [
str(random.choice(combined))
for _ in range(count)
]
def run_with_except(data: List):
t0 = datetime.datetime.now()
numbers = 0
for item in data:
try:
n = int(item)
numbers += 1
except:
pass
dt = datetime.datetime.now() - t0
print(
f'EXCEPT: Done in {dt.total_seconds() * 1000:,.0f} ms, {numbers:,} numbers and {len(data) - numbers:,} letters.')
def run_with_test(data: List):
t0 = datetime.datetime.now()
numbers = 0
for item in data:
if item.isnumeric():
n = int(item)
numbers += 1
dt = datetime.datetime.now() - t0
print(
f'TEST: Done in {dt.total_seconds() * 1000:,.0f} ms, {numbers:,} numbers and {len(data) - numbers:,} letters.')
if __name__ == '__main__':
main()
@mikeckennedy

This comment has been minimized.

Copy link
Owner Author

@mikeckennedy mikeckennedy commented Jul 9, 2020

Output on my Macbook:

EXCEPT: Done in 663 ms, 311,656 numbers and 688,344 letters.
TEST: Done in 107 ms, 311,656 numbers and 688,344 letters.

Process finished with exit code 0
@parberge

This comment has been minimized.

Copy link

@parberge parberge commented Aug 4, 2020

Hm, this comes as a surprise for me. I thought "It's easier to ask for forgiveness than permission" meant it was always better with try/catch.

Very good example, thanks!

@mikeckennedy

This comment has been minimized.

Copy link
Owner Author

@mikeckennedy mikeckennedy commented Aug 4, 2020

You're welcome! It is easier to read and easier to maintain often. And many times you have to account for exceptions at lower levels to sorta require both. Therefore, code-wise, it's easier, but in raw perf, it's not necessarily faster. :)

@madig

This comment has been minimized.

Copy link

@madig madig commented Oct 3, 2020

Mh, int() can do more than isnumeric() lets through, e.g. int("-1") does the right thing, "-1".isnumeric() won't. All I want is a fast way of going str -> either int or float without using exceptions :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.