Python, or Rediscovering your Love of Programming

The past few weeks I've been coding for job interviews and writing a stock-trading simulator. Almost all of my coding has been in Python, a language I once spurned. Now I'm amazed at just how fast it's possible to write algorithms like A* or data-intense simulations.

Programming languages are not unlike cameras. They both have two main objectives; deliver a great result once the user is ready, and getting out of the way as much as possible to facilitate that process. Java and C++ are excellent at the former, but terrible at the latter.

Last time I tried Python, I was horrified at how slow it was compared to Java. But that was over 10 years ago, computers have gotten an order of magnitude faster since. Java has developed immensely too, with generics, JIT, faster garbage collection, etc. The real change, however, is just how much more acceptable Python's performance has gotten.

In a rough comparison, C++ is usually a bit faster than Java, and roughly 10 times faster than Python. The question is how often that difference matters. When was the last time someone actually rewrote a Java program in C++ for performance reasons? My bet; about five years ago. In the cloud computing age most software is bound not by the CPU, but by the user's internet connection.

Developing a fairly sophisticated web-service in Ruby and PHP can be done in about a week. 10 years ago, it was a tedious affair, often requiring C++ as Java was too resource demanding to scale well. With short development times, programmers can focus their attention on advanced algorithms and disruptive features instead.

The beauty of Python lies in it's simplicity, and potential power if performance is lacking. By putting only the heavy computations in C++ or Cython, we can achieve a perfect balance between ease of coding and performance. Donald Knuth once said "Premature optimization is the root of all evil." Choosing C++ or Java for all your code is premature pre-optimization if a lot of it could be written in Python.

As a simple example, generating a list of the first 10,000 Fibonacci numbers, printing them, and finally printing a random one:

Java:
import java.math.BigInteger;
import java.util.Random;

class Fib {
public static void main(String[] args) {
final int limit = 10000;
BigInteger[] fibs = new BigInteger[limit];
fibs[0] = BigInteger.ZERO;
fibs[1] = BigInteger.ONE;
for (int i = 2; i < limit; ++i) {
fibs[i] = fibs[i-2].add(fibs[i-1]);
System.out.println(fibs[i]);
}
System.out.println(fibs[(new Random()).nextInt(limit)]);
}
}


C++:
#include <gmpxx.h>
#include <iostream>

int main() {
const int limit = 10000;
mpz_class vec[limit];
vec[0] = 0;
vec[1] = 1;

for (int i = 2; i < limit; ++i) {
vec[i] = vec[i-2] + vec[i-1];
std::cout << vec[i] << std::endl;
}
std::cout << vec[rand()%limit] << std::endl;
return 0;
}


Python:
import random

limit = 10000
fibs = [0, 1]
for i in range(2, limit):
fibs.append(fibs[i-2] + fibs[i-1])
print fibs[i]
print fibs[random.randint(0, limit)]


Oh, and the speed? Java (with or without JIT) took 2.7 seconds, Python 0.41 seconds...C++, of course, was faster: 0.18 seconds. Enjoy your coding!





No comments:

Post a Comment