Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Go really be that much faster than Python?

I think I may have implemented this incorrectly because the results do not make sense. I have a Go program that counts to 1000000000:

package main

import (
    "fmt"
)

func main() {
    for i := 0; i < 1000000000; i++ {}
    fmt.Println("Done") 
}

It finishes in less than a second. On the other hand I have a Python script:

x = 0
while x < 1000000000:
    x+=1
print 'Done'

It finishes in a few minutes.

Why is the Go version so much faster? Are they both counting up to 1000000000 or am I missing something?

like image 577
bab Avatar asked Sep 25 '12 01:09

bab


People also ask

Why is Go better than Python?

Golang wins because it is designed to be more productive, simpler to debug, and most importantly, it's easier to read. Python is unquestionably the most common choice for developers who want to formulate a machine learning model.

Should I learn Go or Python 2022?

When it comes to microservices, APIs, and other fast-load features, Golang is absolutely better than Python. But when it comes to natural language processing or machine learning, the robustness and readability of Python (as well as the extensiveness of its libraries) come into play.

Is Python the fastest?

The Speed Issue Taking the fastest individual run times for several popular programming languages from the binary-tree benchmark on The Computer Language Benchmarks Game, Python's 48.03 seconds stand no chance against 0.94 seconds in C++ or 1.54 seconds in C.

Can Python ever be as fast as C?

On my computer, the equivalent implementation in C takes 0.32 seconds. Although C remains the master of speed in general, PyPy can beat C in some cases. “If you want your code to magically run faster, you should probably just use PyPy.”


3 Answers

One billion is not a very big number. Any reasonably modern machine should be able to do this in a few seconds at most, if it's able to do the work with native types. I verified this by writing an equivalent C program, reading the assembly to make sure that it actually was doing addition, and timing it (it completes in about 1.8 seconds on my machine).

Python, however, doesn't have a concept of natively typed variables (or meaningful type annotations at all), so it has to do hundreds of times as much work in this case. In short, the answer to your headline question is "yes". Go really can be that much faster than Python, even without any kind of compiler trickery like optimizing away a side-effect-free loop.

like image 51
hobbs Avatar answered Oct 17 '22 00:10

hobbs


pypy actually does an impressive job of speeding up this loop

def main():
    x = 0
    while x < 1000000000:
        x+=1

if __name__ == "__main__":
    s=time.time()
    main()
    print time.time() - s

$ python count.py 
44.221405983
$ pypy count.py 
1.03511095047

~97% speedup!

Clarification for 3 people who didn't "get it". The Python language itself isn't slow. The CPython implementation is a relatively straight forward way of running the code. Pypy is another implementation of the language that does many tricky (especiallt the JIT) things that can make enormous differences. Directly answering the question in the title - Go isn't "that much" faster than Python, Go is that much faster than CPython.

Having said that, the code samples aren't really doing the same thing. Python needs to instantiate 1000000000 of its int objects. Go is just incrementing one memory location.

like image 74
John La Rooy Avatar answered Oct 17 '22 00:10

John La Rooy


This scenario will highly favor decent natively-compiled statically-typed languages. Natively compiled statically-typed languages are capable of emitting a very trivial loop of say, 4-6 CPU opcodes that utilizes simple check-condition for termination. This loop has effectively zero branch prediction misses and can be effectively thought of as performing an increment every CPU cycle (this isn't entirely true, but..)

Python implementations have to do significantly more work, primarily due to the dynamic typing. Python must make several different calls (internal and external) just to add two ints together. In Python it must call __add__ (it is effectively i = i.__add__(1), but this syntax will only work in Python 3.x), which in turn has to check the type of the value passed (to make sure it is an int), then it adds the integer values (extracting them from both of the objects), and then the new integer value is wrapped up again in a new object. Finally it re-assigns the new object to the local variable. That's significantly more work than a single opcode to increment, and doesn't even address the loop itself - by comparison, the Go/native version is likely only incrementing a register by side-effect.

Java will fair much better in a trivial benchmark like this and will likely be fairly close to Go; the JIT and static-typing of the counter variable can ensure this (it uses a special integer add JVM instruction). Once again, Python has no such advantage. Now, there are some implementations like PyPy/RPython, which run a static-typing phase and should fare much better than CPython here ..

like image 24
14 revs, 3 users 94%user166390 Avatar answered Oct 17 '22 00:10

14 revs, 3 users 94%user166390