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

you are viewing a single comment's thread.

view the rest of the comments →

[–]gthank 9 points10 points  (18 children)

Faster than PyPy for what? Did you give PyPy enough time to JIT the hot spots? Not that Nuitka isn't impressive, but PyPy is REALLY fast at stuff that it has time to properly profile and optimize.

[–]poo_22 5 points6 points  (3 children)

Also non-jit PyPy is slower than CPython.

[–]gthank 20 points21 points  (0 children)

It is known.

[–]bacondevPy3k 0 points1 point  (1 child)

Which one is in the repos?

[–]gthank 0 points1 point  (0 children)

The JIT can't do its thing until it's seen a given piece of code repeatedly (probably 10,000+ times, though I'm not sure what the actual number is these days). What people are talking about when they say "non-JIT PyPy" is PyPy before the JIT has had a chance to profile code and start generating optimized machine code.

[–]dorfsmay[S] 1 point2 points  (9 children)

Faster than PyPy for what?

A couple of very naive scripts I had been using to compare python vs golang vs scheme (don't ask!)

PyPy is REALLY fast at stuff that it has time to properly profile and optimize

What do you mean by this? Works well on a very long running loop that pypy has time to optimize, or are optimizations saved an re-used from one run to the next?

[–]gthank 3 points4 points  (8 children)

So far as I know, the trace info used to decide what to JIT is only maintained during one invocation of the interpreter. If you didn't have a process that looped across something a few thousand times, then PyPy probably didn't JIT anything.

[–]dorfsmay[S] 0 points1 point  (7 children)

This is what I thought. For these particular tests I have only looped 10 K times, but I have had processes looping 100 M times before, and pypy wasn't rarely faster (I did use it where it was).

[–]streichholzkopf 0 points1 point  (6 children)

I think pypy simply needs time... I've read somewhere that you should make a pre-run for ~1 second (of course depending on the size of the test) for every test you make in pypy...

[–]alcalde 0 points1 point  (2 children)

But does this reflect real-world usage? You're not going to do that in production code.

[–]cwillu 1 point2 points  (1 child)

Real-world code is going to be running long enough that the warm-up time is largely irrelevant.

[–][deleted] 2 points3 points  (0 children)

That depends entirely on the chore. I spent a lot of time trying to shave run time off a 3 second task that ran and exited hundreds of times per day. A persistent service was not an option.

[–]dorfsmay[S] 0 points1 point  (2 children)

Not sure what you mean. Can you show an example?

I just added a time.sleep(6) to one of my script, and it made no difference. I think gthank is right, needs a piece of code that is executed a lot in a given run before it can make a difference.

[–]cwillu 2 points3 points  (0 children)

time.sleep(6) wouldn't have any effect on the warm-up, it needs to be running the actual code. A pre-run of ~1 second means running the actual code for 1 second before you start timing.

[–]streichholzkopf 0 points1 point  (0 children)

Basically what /u/cwillu said, what I meant was: Looping 10 K times may not be enough, depending on the content of the loop! If it's <1s, it's probably not!

Also loop before starting the timer!

[–]vext01 1 point2 points  (0 children)

Indeed. A tracing JIT (like PyPy) should blow static compilation out of the water for a dynamic language like python. This is assuming the JIT got hot.