-5

I am practicing at leedcode writing solution in golang and rust. I wrote a solution for this problem https://leetcode.com/problems/letter-combinations-of-a-phone-number/ in golang and in rust

package main

func letterCombinations(digits string) []string {
    if len(digits) == 0 {
        return []string{}
    }

    letters := [][]string{
        {},
        {},
        {"a", "b", "c"},
        {"d", "e", "f"},
        {"g", "h", "i"},
        {"j", "k", "l"},
        {"m", "n", "o"},
        {"p", "q", "r", "s"},
        {"t", "u", "v"},
        {"w", "x", "y", "z"},
    }

    var gen func(index int, digits string) []string
    gen = func(index int, digits string) []string {
        result := make([]string, 0)
        row := letters[int(digits[index]-'0')]
        index++
        for _, letter := range row {
            if index < len(digits) {
                for _, res := range gen(index, digits) {
                    result = append(result, letter+res)
                }
            } else {
                result = append(result, letter)
            }
        }

        return result
    }

    return gen(0, digits)
}

func main() {
    for i := 0; i < 10000; i++ {
        letterCombinations("23456789")
    }
}

and this in rust

struct Solution;

impl Solution {
    pub fn letter_combinations(digits: String) -> Vec<String> {
        if digits.len() == 0 {
            return vec![];
        }

        let letters: [[char; 5]; 10] = [
            [0 as char, '0', '0', '0', '0'],
            [0 as char, '0', '0', '0', '0'],
            [3 as char, 'a', 'b', 'c', '0'], // 2
            [3 as char, 'd', 'e', 'f', '0'], // 3
            [3 as char, 'g', 'h', 'i', '0'], // 4
            [3 as char, 'j', 'k', 'l', '0'], // 5
            [3 as char, 'm', 'n', 'o', '0'], // 6
            [4 as char, 'p', 'q', 'r', 's'], // 7
            [3 as char, 't', 'u', 'v', '0'], // 8
            [4 as char, 'w', 'x', 'y', 'z'], // 9
        ];

        fn gen(index: usize, digits: &str, letters: [[char; 5]; 10]) -> Vec<String> {
            let result_capacity = (4 as usize).pow(digits.len() as u32);
            let mut result: Vec<String> = Vec::with_capacity(result_capacity);
            let iletters = digits.chars().nth(index).unwrap().to_digit(10).unwrap() as usize;
            let row = letters[iletters];
            let index = index + 1;
            for i in 1..= row[0] as usize {
                if index < digits.len() {
                    let res = gen(index, digits, letters);
                    for j in 0..res.len() {
                        let mut line = String::with_capacity(res[j].len() + 1);
                        line.push(row[i]);
                        line.push_str(&res[j]);
                        result.push(line);
                    }
                } else {
                    result.push(row[i].to_string());
                }
            }
            return result;
        }

        return gen(0, &digits, letters);
    }
}

fn main() {
    for _i in 0..10000 {
        Solution::letter_combinations(String::from("23456789"));
    }
}

Where I run each solution through 10 000 iterations. Golang solution takes 60 seconds on my laptop. Rust solution takes 556 seconds which is about 10 times slower. I guess it because golang garbage collector does not return heap memory to OS during program and use pre-allocated memory for each iteration. But rust every call of function letterCombinations() allocates memory from OS and frees it back. So rust slower. Am I correct?

Anonymous
  • 77
  • 1
  • 7
  • 8
    Did you compile the Rust code in release mode? – interjay Sep 05 '21 at 11:30
  • 3
    [Don't use LeetCode for Rust.](https://github.com/pretzelhammer/rust-blog/blob/master/posts/learning-rust-in-2020.md#leetcode) – trent Sep 05 '21 at 12:00
  • 1
    > Did you compile the Rust code in release mode? you are right I used debug mode. I have tried with release and rust solution takes about as golang one. Thank you. I am new in rust and did not realized debug mode can be so slow. – Anonymous Sep 05 '21 at 13:36
  • 1
    [Why is my Rust program slower than the equivalent Java program?](https://stackoverflow.com/q/25255736/3650362) – trent Sep 05 '21 at 14:19

1 Answers1

2

As noted elsewhere (e.g., Why is my Rust program slower than the equivalent Java program?), if you compile Rust code in debug mode, it tends to be slow. If you turn on optimization, it tends to be much faster.

It's worth mentioning here that Rust compilers will do a great deal of optimization if you let them (or tell them). The cargo build system will do this when run in release mode. This optimization can make debugging very hard! So if you're trying to get code working, you probably don't want to do this yet.

Go compilers traditionally just do relatively simple optimization.1 So go build currently doesn't have an optimization level or flag, except for -N to disable optimization and -l to disable inlining.


1This optimization is not useless, but it's not the kind of super-fancy makes-following-your-code-in-the-debugger-impossible optimization that rustc does at high optimization levels.

torek
  • 448,244
  • 59
  • 642
  • 775