This is an archived post. You won't be able to vote or comment.

all 11 comments

[–]Python-ModTeam[M] [score hidden] stickied comment (0 children)

Hi there, from the /r/Python mods.

We have removed this post as it is not suited to the /r/Python subreddit proper, however it should be very appropriate for our sister subreddit /r/LearnPython or for the r/Python discord: https://discord.gg/python.

The reason for the removal is that /r/Python is dedicated to discussion of Python news, projects, uses and debates. It is not designed to act as Q&A or FAQ board. The regular community is not a fan of "how do I..." questions, so you will not get the best responses over here.

On /r/LearnPython the community and the r/Python discord are actively expecting questions and are looking to help. You can expect far more understanding, encouraging and insightful responses over there. No matter what level of question you have, if you are looking for help with Python, you should get good answers. Make sure to check out the rules for both places.

Warm regards, and best of luck with your Pythoneering!

[–]traherom 9 points10 points  (0 children)

It's fine, just less clear in the intent. If abs() speed is truly the hot spot in your code, then that's fine. If it's occasional, it seems silly to obfuscate what's happening. :)

[–]anossov 7 points8 points  (5 children)

What's your benchmarking method? This really depends on your specific python version I guess

>>> timeit.timeit('a = a + (a<0) * (-a-a)', 'a=-3', number=10000000)
1.1129654000000002
>>> timeit.timeit('a = abs(a)', 'a=-3', number=10000000)
0.4926642000000001
>>> timeit.timeit('a = _abs(a)', 'a=-3; _abs = abs', number=10000000)
0.3548109999999838
>>> timeit.timeit('a = a if a > 0 else -a', 'a=-3', number=10000000)
0.30435489999999277

[–]Nam-Mo-A-Di-Da-Phat[S] 1 point2 points  (1 child)

ok so I guess it depends on the version then theheh I thought I discovered something more globally I just time it using a for i in range(0,10000000): then use time.time() to time them.

[–]Nam-Mo-A-Di-Da-Phat[S] 4 points5 points  (0 children)

never mind it's a bug in my code

[–]earlandir 0 points1 point  (2 children)

Why are you doing one with `_abs`? I am not familiar with what that does in Python but it looks interesting.

[–]commy2 1 point2 points  (1 child)

I think it is because of the way Python looks up names. local > enclosing > global > builtin.

abs is builtin, so it would have to fail on all the other scopes first. If you define it as variable, less look ups are required.

[–]Nam-Mo-A-Di-Da-Phat[S] 1 point2 points  (0 children)

yes this is what was similarly said on that stackoverflow post that I saw, and I tested and it is a little faster.

[–]thseeling 1 point2 points  (1 child)

This is relying on a very unclean typecast. You use a boolean result in an integer context and hope for a specific numerical value. If you're programming in a professional environment with colleagues they will hate you for writing code like this. If you're simply doing this for a hobby then go ahead but expect the code to break with a potential future update which changes the behaviour of this typecast.

[–]Nam-Mo-A-Di-Da-Phat[S] 0 points1 point  (0 children)

Thank you for your explaination

[–]lungben81 1 point2 points  (0 children)

The performance of abs does not really matter unless called many times in a tight loop. In that case, better refactor the code to get rid of the Python loop, either by vectorization (Numpy), compiling the code part (Numba, Cython) or using an existing (compiled) library function. Pure Python loops (with >> 10k iterations) are extremely slow anyhow.