3

In python3, let's say I got a situation where I need a integer. Is it faster to do something like

processed_number = int(round(float(some_input)))

or should I do this:

if some_input is int:
    processed_number = some_input
else:
    processed_number = int(round(float(some_input)))

or perhaps

try:
    some_statement_taht_needs_int(some_input)
# except TypeError:
#    processed_number = int(round(float(some_input)))
#    some_statement_taht_needs_int(some_input)
# Apparently, it's better to cut down on exception handling: I might handle something the wrong way
except ValueError:
    # The same thing
    processed_number = int(round(float(some_input)))
    some_statement_taht_needs_int(some_input)

I'm sorry if that was a dumb question since both use function calls. I'm just wondering if there is a significant time difference between each method. I know I shouldn't be optimizing python code too much but this is just a question (a possibly dumb one) that I had for a long time. Please don't burn me down if this is dumb.


I'm not really making code that needs this optimization (for now); this is just a question so I can improve my code in the future.

theX
  • 1,008
  • 7
  • 22
  • It really depends on 1) what your condition is, 2) how often you could error out. Try-except is faster if you don't expect to error out except in exceptional circumstances (data or server failure). If you're using it as a flow control mechanism that's not a good idea. – cs95 Jun 28 '20 at 22:43
  • What if I'm using it for pre-processing inputs (like when defining a function or when defining an object/class) – theX Jun 28 '20 at 22:47
  • You're essentially asking about two commonly used approaches: EAFP and LBYL. The answer is... it depends, on your code and your circumstance. Here's a discussion on the same topic, but for Java: https://stackoverflow.com/questions/404795/lbyl-vs-eafp-in-java FWIW I don't necessarily agree with the opinions in the accepted answer there, but that's for you to judge. – cs95 Jun 28 '20 at 22:50
  • 2
    `if some_input is int:` is testing if the input is the class `int`... – ShadowRanger Jun 28 '20 at 22:50
  • Your final option is a bad one; in addition to a lot of repeating yourself, it's catching very common error types that might be raised for reasons other than your input's type/value, causing you to handle exceptions you don't expect. Limit the scope of your `try`s as much as possible, to avoid accidentally handling exceptions caused by problems you don't expect and can't reasonably handle. – ShadowRanger Jun 28 '20 at 22:52
  • Oh, I didn't know that! @ShadowRanger , Thank you for telling me that! – theX Jun 28 '20 at 22:53
  • @theX: If you actually wanted type-checking, `if isinstance(some_input, int):` (or `isinstance(some_input, numbers.Integral)` to allow `int`-like classes matching the ABC) is traditional; to forbid subclasses, you could do the somewhat worse `if type(some_input) is int:`. That said, usually, you don't do any of this; your API just says "requires `int`" and you let the exception bubble if the user fails to adhere to the API contract. – ShadowRanger Jun 28 '20 at 22:55
  • Hold on: so you're saying `if isinstance(some_input, some_class):`, `if type(some_input) is some_class` are 2 different ways, right @ShadowRanger? Isn't `if some_input is some_class` also another way? I'll do some profiling later. – theX Jun 28 '20 at 23:00
  • @theX: No. The `is` operator is an identity test. It's saying "are these the exact same object", in this case asking if `some_input` is identical to (bound to the same underlying object representing) the class `int`. It would only return `True` if at some earlier point someone had done something like `some_input = int`, but would fail for `some_input = 1` (because `1` is an *instance* of `int`, but is not `int`, the class). `type(some_input) is int` works because it converts from `1` to `int` (determining the class of `1`) before checking. – ShadowRanger Jun 28 '20 at 23:34
  • @ShadowRanger, Oh! I see. – theX Jun 28 '20 at 23:48

1 Answers1

1

Usually you would not expect to be doing this so often that it is a dominant performance issue. You are likely to have some other part of your code that is the performance limiting factor.

It is usually best to code these things in the way that is cleanest and is most obvious for the next person who looks at your code to understand. Do not get hung up on premature optimization. Unless it is something that is extremely obviously slow and will happen a lot, just write your code the cleanest and clearest way. If necessary afterward you find it is slow, you can profile it to find out where it is slow and fix that.

You will usually find these kinds of things are not where the issues lie.

Glenn Mackintosh
  • 2,765
  • 1
  • 10
  • 18
  • I was asking for performance, and this is a nice answer. But the other comments, telling me EAFP is the way to go so. But since your telling me that, here's my final conclusion: **I will use EAFP unless it makes anything less clear than nested functions** – theX Jun 28 '20 at 23:09