Is Python Faster and Lighter Than C++

Is Python faster and lighter than C++?

I think you're reading those stats incorrectly. They show that Python is up to about 400 times slower than C++ and with the exception of a single case, Python is more of a memory hog. When it comes to source size though, Python wins flat out.

My experiences with Python show the same definite trend that Python is on the order of between 10 and 100 times slower than C++ when doing any serious number crunching. There are many reasons for this, the major ones being: a) Python is interpreted, while C++ is compiled; b) Python has no primitives, everything including the builtin types (int, float, etc.) are objects; c) a Python list can hold objects of different type, so each entry has to store additional data about its type. These all severely hinder both runtime and memory consumption.

This is no reason to ignore Python though. A lot of software doesn't require much time or memory even with the 100 time slowness factor. Development cost is where Python wins with the simple and concise style. This improvement on development cost often outweighs the cost of additional cpu and memory resources. When it doesn't, however, then C++ wins.

Why is my python 3 implementation much faster than the one I wrote in C++?

The main problem is that you're reseeding a random number generator for each random number in your C++ code. Additionally you're not compiling with optimizations enabled (-O3).

I moved the initialization of the random number generator outside the randomFloat function (equally, you could use static variables inside the function):

random_device rd;
default_random_engine generator(rd()); // rd() provides a random seed
uniform_real_distribution<float> distribution(0,1);

float randomFloat() {
float x = distribution(generator);
return x;
}

and compiled with -O3 and now C++ is considerably faster than Python


Another possibility could be that python and C++ code use a different random number generator. Python random module (C code here) uses a MT19937 Mersenne Twister random number generator that is a fast PRNG optimized specifically for numerical problems such as Monte Carlo; the algorithm of default_random_engine in C++ is implementation-defined. As pointed out by Melak47, you can force the use of MT19937 PRNG in C++ with:

mt19937 generator(rd());

or

mt19937_64 generator(rd());

P.S., Python outperforming C++ is not unheard of; the C++ algorithms value genericity whereas the Python algorithms are often quite optimized for some use cases. See for example this question on substring matching.

Why does my python function run faster than the one in c++?

There are many reasons why this performance test does not give useful results.

  1. Don't compare, or pay attention to, release timing. The entire point of using a language like C or C++ is to enable (static) compiler optimizations. So really, the results are the same. On the other hand, it is important to make sure that aggressive compiler optimizations don't optimize out your entire test (due to the result of computation going unused, or due to undefined behaviour anywhere in your program, or due to the compiler assuming that part of the code can't actually be reached because it there would be undefined behaviour if it were reached).

  2. for i in [x]: is a pointless loop: it creates a Python list of one element, and iterates once. That one iteration does i *= a, i.e., it multiplies i, which is the Numpy array. The code only works accidentally; it happens that Numpy arrays specially define * to do a loop and multiply each element. Which brings us to...

  3. The entire point of using Numpy is that it optimizes number-crunching by using code written in C behind the scenes to implement algorithms and data structures. i simply contains a pointer to a memory allocation that looks essentially the same as the one the C program uses, and i *= a does a few O(1) checks and then sets up and executes a loop that looks essentially the same as the one in the C code.

  4. This is not reliable timing methodology, in general. That is a whole other kettle of fish. The Python standard library includes a timeit module intended to make timing easier and help avoid some of the more basic traps. But doing this properly in general is a research topic beyond the scope of a Stack Overflow question.


"But I want to see the slow performance of native Python, rather than Numpy's optimized stuff - "

If you just want to see the slow performance of Python iteration, then you need for the loop to actually iterate over the elements of the array (and write them back):

def mult(x, a):
for i in range(len(x)):
x[i] *= a

Except that experienced Pythonistas won't write the code that way, because range(len( is ugly. The Pythonic approach is to create a new list:

def mult(x, a):
return [i*a for i in x]

That will also show you the inefficiency of native Python data structures (we need to create a new list, which contains pointers to int objects).

On my machine, it is actually even slower to process the Numpy array this way than a native Python list. This is presumably because of the extra work that has to be done to interface the Numpy code with native Python, and "box" the raw integer data into int objects.

Is C notably faster than C++

C++ is often used for scientific programs. The popularity of C may be waning in that domain. Fortran remains popular as a "low-level" language.

In C++, "you only pay for what you use." So there is nothing that would make it any slower than C. In particular for scientific programs, expression templates make it possible to perform some custom optimization using the template engine to process program semantics.

The reason C is preferred for projects such as Python is that it tends to be less confusing to read, so a large codebase will be more accessible to a larger pool of contributors.

SQLite has a requirement for small executable code size, where C does have a slight edge. Judicious use of C++ still allows use in embedded applications, but it is less popular due to fear that unwanted language features will creep in.

Python with Numpy/Scipy vs. Pure C++ for Big Data Analysis

First off, if the bulk of your "work" comes from processing huge text files, that often means that your only meaningful speed bottleneck is your disk I/O speed, regardless of programming language.


As to the core question, it's probably too opinion-rich to "answer", but I can at least give you my own experience. I've been writing Python to do big data processing (weather and environmental data) for years. I have never once encountered significant performance problems due to the language.

Something that developers (myself included) tend to forget is that once the process runs fast enough, it's a waste of company resources to spend time making it run any faster. Python (using mature tools like pandas/scipy) runs fast enough to meet the requirements, and it's fast to develop, so for my money, it's a perfectly acceptable language for "big data" processing.

Should I use a code converter (Python to C++)?

Generally it's an awful way to write code, and does not guarantee that it will be any faster. Things which are simple and fast in one language can be complex and slow in another. You're better off either learning how to write fast Python code or learning C++ directly than fighting with a translator and figuring out how to make the generated code run acceptably.

Is else if faster than switch() case?

For just a few items, the difference is small. If you have many items you should definitely use a switch.

If a switch contains more than five items, it's implemented using a lookup table or a hash list. This means that all items get the same access time, compared to a list of if:s where the last item takes much more time to reach as it has to evaluate every previous condition first.

Are tuples more efficient than lists in Python?

The dis module disassembles the byte code for a function and is useful to see the difference between tuples and lists.

In this case, you can see that accessing an element generates identical code, but that assigning a tuple is much faster than assigning a list.

>>> def a():
... x=[1,2,3,4,5]
... y=x[2]
...
>>> def b():
... x=(1,2,3,4,5)
... y=x[2]
...
>>> import dis
>>> dis.dis(a)
2 0 LOAD_CONST 1 (1)
3 LOAD_CONST 2 (2)
6 LOAD_CONST 3 (3)
9 LOAD_CONST 4 (4)
12 LOAD_CONST 5 (5)
15 BUILD_LIST 5
18 STORE_FAST 0 (x)

3 21 LOAD_FAST 0 (x)
24 LOAD_CONST 2 (2)
27 BINARY_SUBSCR
28 STORE_FAST 1 (y)
31 LOAD_CONST 0 (None)
34 RETURN_VALUE
>>> dis.dis(b)
2 0 LOAD_CONST 6 ((1, 2, 3, 4, 5))
3 STORE_FAST 0 (x)

3 6 LOAD_FAST 0 (x)
9 LOAD_CONST 2 (2)
12 BINARY_SUBSCR
13 STORE_FAST 1 (y)
16 LOAD_CONST 0 (None)
19 RETURN_VALUE


Related Topics



Leave a reply



Submit