Rust 性能分析

时间:2024-06-07 15:02:19

都说Rust性能好,但是也得代码写得好,猜猜下面两个代码哪个快

. - 力扣(LeetCode)

use std::collections::HashMap;
use lazy_static::lazy_static;

lazy_static! {
    static ref DIGIT: HashMap<char, usize> = {
        let mut m = HashMap::new();
        for c in '1'..':' {
            m.insert(c, Solution::to_digit(c) as usize - 1);
        }
        m
    };
}

impl Solution {
    pub fn to_digit(c: char) -> u32 {
        match c.to_digit(10) {
            None => 0,
            Some(i) => i,
        }
    }
    pub const SUB_INDEX: [[usize; 9]; 9] = [
        [0, 0, 0, 1, 1, 1, 2, 2, 2],
        [0, 0, 0, 1, 1, 1, 2, 2, 2],
        [0, 0, 0, 1, 1, 1, 2, 2, 2],
        [3, 3, 3, 4, 4, 4, 5, 5, 5],
        [3, 3, 3, 4, 4, 4, 5, 5, 5],
        [3, 3, 3, 4, 4, 4, 5, 5, 5],
        [6, 6, 6, 7, 7, 7, 8, 8, 8],
        [6, 6, 6, 7, 7, 7, 8, 8, 8],
        [6, 6, 6, 7, 7, 7, 8, 8, 8],
    ];
    pub fn is_valid_sudoku(board: Vec<Vec<char>>) -> bool {
        let mut line_count: [[i32; 9]; 9] = [[0; 9]; 9];
        let mut colume_count: [[i32; 9]; 9] = [[0; 9]; 9];
        let mut sub_count: [[i32; 9]; 9] = [[0; 9]; 9];
        let mut i = 0;
        let mut j = 0;
        for line in board {
            for colume in line {
                if colume != '.' {
                    let digit = match DIGIT.get(&colume) {
                        Some(i) => *i,
                        None => return false
                    };
                    if line_count[i][digit] == 0 {
                        line_count[i][digit] = 1;
                    } else {
                        return false;
                    }
                    if colume_count[j][digit] == 0 {
                        colume_count[j][digit] = 1;
                    } else {
                        return false;
                    }
                    if sub_count[Solution::SUB_INDEX[i][j]][digit] == 0 {
                        sub_count[Solution::SUB_INDEX[i][j]][digit] = 1;
                    } else {
                        return false;
                    }
                }
                j += 1;
            }
            j = 0;
            i += 1;
        }
        true
    }
}
use std::collections::HashSet;
impl Solution {
    pub fn is_valid_sudoku(board: Vec<Vec<char>>) -> bool {
        let mut row:HashSet<char> = HashSet::with_capacity(9);
        let mut blocks:Vec<HashSet<char>> = vec![HashSet::with_capacity(9);3];
        let mut col:Vec<HashSet<char>> = vec![HashSet::with_capacity(9);9];
        for (idx,i) in board.iter().enumerate(){
            if idx % 3 == 0{
                for i in 0..3{
                    blocks[i].clear();
                }
            }
            for (jdx,&j) in i.iter().enumerate(){
                if j == '.'{
                    continue;
                }
                let temp = jdx/3;
                if row.contains(&j) || col[jdx].contains(&j) || blocks[temp].contains(&j) {
                    //println!("{},{}",idx,jdx);
                    return false;
                }
                row.insert(j);
                col[jdx].insert(j);
                blocks[temp].insert(j);
            }
            row.clear();
        }
        true
    }
}

Perf 分析 Perf+火焰图进行性能瓶颈分析-****博客

const BOARD_ARR:[[char; 9]; 9] = [
        ['5', '3', '.', '.', '7', '.', '.', '.', '.'],
        ['6', '.', '.', '1', '9', '5', '.', '.', '.'],
        ['.', '9', '8', '.', '.', '.', '.', '6', '.'],
        ['8', '.', '.', '.', '6', '.', '.', '.', '3'],
        ['4', '.', '.', '8', '.', '3', '.', '.', '1'],
        ['7', '.', '.', '.', '2', '.', '.', '.', '6'],
        ['.', '6', '.', '.', '.', '.', '2', '8', '.'],
        ['.', '.', '.', '4', '1', '9', '.', '.', '5'],
        ['.', '.', '.', '.', '8', '.', '.', '7', '9'],
    ];

fn main() {    
    let mut board: Vec<Vec<char>> = Vec::new();
    for arr in BOARD_ARR {
        let line: Vec<char> = Vec::from(arr);
        board.push(line);
    }

    let mut result: bool = false;
    let start = Instant::now();
    for _i in 1..10000 {
        result = Solution::is_valid_sudoku(board.clone());
    }
    println!("is_valid_sudoku {:?}", start.elapsed());
    
    let start = Instant::now();
    for _i in 1..10000 {
        result = Solution::is_valid_sudoku2(board.clone());
    }
    println!("is_valid_sudoku2 {:?}", start.elapsed());

    println!("{}", result);
}

 clone比较费时:

MacBook-Pro:is_valid_sudoku mac$  ./target/release/is_valid_sudoku
is_valid_sudoku 23.554336ms
is_valid_sudoku2 66.421909ms
true

改成引用之后:

MacBook-Pro:is_valid_sudoku mac$  ./target/release/is_valid_sudoku
is_valid_sudoku 6.21774ms
is_valid_sudoku2 47.475271ms
true