The following post will show the results obtained after running experiments with different programming languages. Which one will be faster? Which one is easier?
A few months ago, I explained the advantages of choosing the right way to program a loop (More). However, always using Python as the programming language. In this case, we are going to check how the programming language can influence the execution time of the same code.
It is important to emphasize that we are not going to perform execution optimizations or the use of Big Data and Cloud alternatives such as Spark, Hadoop, Big Query...
First, we need to know a little about each programming language.
> Python: It is an interpreter language that has grown in recent years because of its use in data analysis, artificial intelligence and even web programming. It is a fairly easy programming language but sometimes has performance drops because it has to interpret all the code, although it is gradually improving.
> R: It is a language that is widely used by data analysts because it has a more intuitive way of programming where everything works by tables known as dataframes.
> Julia: It is a programming language that has been created to offer the return in the most optimal and fast way, reaching execution times similar to C++.
> GO: It is a programming language a little less known, but it is becoming popular among most enthusiasts. This is because it is easy to understand because it has a syntax very similar to Python, but at certain times achieves runtimes similar to C++.
1. Create two lists/arrays and multiply
In the first experiment, we will create two lists and then multiply each element. This usually has a bad performance in Python because you have to loop the lists several times and, in this case, each one has 100000000 elements.
Python
First, a test has been done creating the lists with 'for' and without list comprehension, however, being sequential the result is very bad, obtaining an execution time of 88 seconds.
import random
import time
first = []
second = []
start_time = time.time()
for i in range(100000000):
first.append(random.random())
second.append(random.random())
rst = []
for num_1, num_2 in zip(first, second):
rst.append(num_1 * num_2)
print("--- %s seconds ---" % (time.time() - start_time))
Numpy
Numpy is implemented so that the manipulation of lists and arrays works in the most optimal way possible, because of this we obtain an execution time of 2.5 seconds, which is 97.16% less.
import numpy as np
import time
start_time = time.time()
first = np.random.rand(100000000)
second = np.random.rand(100000000)
rst = np.multiply(first, second)
print("--- %s seconds ---" % (time.time() - start_time))
R
R manages to improve the time to a run time of 1.28 seconds.
start_time <- Sys.time()
first = rnorm(10000000)
second = rnorm(10000000)
rst = first*second
end_time <- Sys.time()
end_time - start_time
Go
The disadvantage of Go is that it does not have a library that is in charge of creating the lists, in this case, we must create them by going through all the positions of the lists. Even so, it achieves an even smaller runtime., 0.338 segundos.
package main
import "math/rand"
import "time"
import "fmt"
func main(){
start := time.Now()
var sized int = 10000000
first := make([]float32, sized)
second := make([]float32, sized)
rst := make([]float32, sized)
for i:=0; i<sized; i++ {
first[i] = rand.Float32()
second[i] = rand.Float32()
}
for i:=0; i<sized; i++ {
rst[i] = first[i]*second[i]
}
finish := time.Since(start)
fmt.Printf("Time: ", finish)
}
Julia
Using Julia you can see that it is developed for speed. It manages to lower the execution time down to 0.150 seconds. This means a decrease of 99.83% compared to Python and 94.02% compared to Numpy.
@time multiply()
using BenchmarkTools
using Distributions
function multiply()
first = rand(10000000)
second = rand(10000000)
rst = first .* second
end
@time multiply()
Below we can see graphically the difference in the execution time of each language.
Execution time with Python
Execution time without Python
As can be seen, the performance of this code is significantly better in Julia.
2. Recursion (Fibonacci)
Python
One of the problems of python is the high cost of recursion, so we have implemented the search for a value in the Fibonacci sequence. To have a higher load, the calculation is used to find the number 40 of the sequence. In Python, we obtained an execution time of 25.47 seconds.
import time
def fibo(n):
if n <= 1:
return n
else:
return(fibo(n-1) + fibo(n-2))
num = 40
start_time = time.time()
print("Fibonacci->", fibo(num))
print("--- %s seconds ---" % (time.time() - start_time))
R
The execution time in R increases significantly to almost 2 minutes.
fibo <- function(n) {
if (n <= 1) {
return(n)
} else {
return(fibo (n-1) + fibo (n-2))
}
}
num = 40
start_time <- Sys.time()
fibo(num)
end_time <- Sys.time()
end_time - start_time
Go
In Go the performance is very good since the execution time is completely reduced compared to python and r, reaching up to 0.543 seconds.
package main
import "math/rand"
import "time"
import "fmt"
func fibo(n int) int {
if (n <= 1){
return n
}else {
return (fibo(n-1) + fibo(n-2))
}
}
func main(){
start := time.Now()
fmt.Printf("Fibo: ", fibo(40))
finish := time.Since(start)
fmt.Printf("Time: ", finish)
}
Julia
Julia, as with the first test, returns the fastest result compared to all programming languages, 0.428 seconds.
using BenchmarkTools
using Distributions
function fibo(n)
if n <=1
return n
else
return fibo(n-1) + fibo(n-2)
end
end
num = 40
@time println("Fibo value: ", fibo(num))
Below we can see graphically the difference in the execution time of each language.
Execution time - Fibonacci
Conclusion
Over the last few years, I have heard a lot about Julia and Go because they are easier to learn and better optimized than Python. Also, Python is object oriented unlike Julia and Go. It has been noted that the performance of these two is much better, however, it currently has far fewer libraries than Python and for some fields such as data science, it can be a bit more laborious.