Ackermann function in Rust
I realized that the nested Records never go more than 3 deep (outermost, middle, innermost), which means it could be rewritten to use primitive arrays.

Comparison 1:

n: 20
fas_ack -&gt; 8388605 took PT0.399960323S
arr_ack -&gt; 8388605 took PT0.115302129S
n: 25
fas_ack -&gt; 268435453 took PT11.283535003S
arr_ack -&gt; 268435453 took PT3.553065491S
n: 30
fas_ack -&gt; 8589934589 took PT757.605898139S
arr_ack -&gt; 8589934589 took PT233.040801010S


Comparison 2:

n: 20
fas_ack -&gt; 8388605 took PT0.807311828S
arr_ack -&gt; 8388605 took PT0.442201425S
n: 25
fas_ack -&gt; 268435453 took PT35.765848937S
arr_ack -&gt; 268435453 took PT14.004015773S
n: 30
fas_ack -&gt; 8589934589 took PT959.685955407S
arr_ack -&gt; 8589934589 took PT141.390498532S


Updated code:

extern crate time;

use time::PreciseTime;

fn main() {
    let m = 3;

    for n in [20, 25, 30].iter() {
        println!("n: {}", n);
        let s = PreciseTime::now();
        let res = arr_ack(m, *n);
        let e = PreciseTime::now();
        println!("arr_ack -&gt; {} took {}", res, s.to(e))
    }
}

fn arr_ack(m: u64, n: u64) -&gt; u64 {
    let mut cache: [u64; 6] = [0; 6];
    cache[0] = 1;
    for m_builder in 0..m {
        cache = _arr_ack(m_builder, 1, cache)
    }
    for n_builder in 1..(n + 1) {
        cache = _arr_ack(m, n_builder, cache)
    }
    cache[0]
}

fn _arr_ack(m: u64, n: u64, mut cache: [u64; 6]) -&gt; [u64; 6] {
    if m == 0 {
        [n + 1, 0, 0, 0, 0, 0]
    } else if m == 1 {
        [n + 2, 0, 0, 0, 0, 0]
    } else if n == 0 {
        let mut new_cache = [1, 0, 0, 0, 0, 0];
        for m_builder in 0..m {
            new_cache = _arr_ack(m_builder, 1, new_cache);
        }
        new_cache
    } else if n == 1 {
        let previous_result = cache[0];
        for n_builder in 2..(previous_result + 1) {
            cache = _arr_ack(m - 1, n_builder, cache);
        }
        [cache[0], previous_result, cache[0], cache[1], cache[2], cache[3]]
    } else {
        let previous_result = cache[0];
        let mut new_cache = [cache[2], cache[3], cache[4], cache[5], 0, 0];
        for n_builder in (cache[1] + 1)..(previous_result + 1) {
            new_cache = _arr_ack(m - 1, n_builder, new_cache);
        }
        [new_cache[0], previous_result, new_cache[0], new_cache[1], new_cache[2], new_cache[3]]
    }
}