Python & Rust

def energy(state):
    e = 0
    for i in range(len(state) - 1):
        e += state[i] * state[i + 1]
    
    if len(state) >= 2:
        e += state[0] * state[-1]
    
    return e
fn energy(state: Vec<f64>) -> f64 {
    let mut e = 0.0;
    for i in 0..state.len() - 1 {
        e += state[i] * state[i + 1];
    }
    if state.len() >= 2 {
        e += state[0] * state[state.len() - 1];
    }
    e
}
  • duck typing
  • many libraries easy to install
  • static and strong typing
  • many libraries easy to install
  • do everything at compilation

Easy

Compiled and fast

import ising

ising.energy([1, 1, 1, -1, -1])
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

#[pymodule]
fn ising(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_wrapped(wrap_pyfunction!(energy))?;
    Ok(())
}

#[pyfunction]
fn energy(state: Vec<f64>) -> f64 {
    let mut e = 0.0;
    for i in 0..state.len() - 1 {
        e += state[i] * state[i + 1];
    }
    if state.len() >= 2 {
        e += state[0] * state[state.len() - 1];
    }
    e
}
def insertion_sort(input):
    output = []
    for value in input:
        i = 0
        for other in output:
            if value <= other:
                break
            i += 1
        output.insert(i, value)
    return output
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

#[pyfunction]
fn insertion_sort(input: Vec<i64>) -> Vec<i64> {
    let mut output = Vec::new();
    for value in input {
        let mut i = 0;
        for &other in &output {
            if value <= other {
                break
            }
            i += 1;
        }
        output.insert(i, value);
    }
    output
}

#[pymodule]
fn bench(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_wrapped(wrap_pyfunction!(insertion_sort))?;
    Ok(())
}

Benchmark

x = list(range(5000))
random.shuffle(x)

insertion_sort(x)
# takes 281 ms

bench.insertion_sort(x)
# takes 2.76 ms

100x faster

+

=

Conclusion