Rust 语言 实现代码行数统计工具 按语言 / 目录分类统计

Rust阿木 发布于 1 天前 3 次阅读


Rust 语言代码行数统计工具实现与优化

在软件开发过程中,代码行数统计是一个常见的需求。它可以帮助开发者了解项目的规模、代码复杂度以及团队的工作量。对于Rust语言,由于其独特的所有权和借用机制,统计代码行数并按语言和目录分类统计显得尤为重要。本文将介绍如何使用Rust语言实现一个简单的代码行数统计工具,并对其性能和功能进行优化。

实现步骤

1. 项目结构

我们需要创建一个Rust项目,并定义项目结构。以下是项目的基本结构:


code_line_counter/
├── src/
│ ├── main.rs
│ └── counter.rs
└── Cargo.toml

在`Cargo.toml`文件中,我们需要添加必要的依赖项:

toml
[package]
name = "code_line_counter"
version = "0.1.0"
edition = "2021"

[dependencies]
walkdir = "2.3.2"
regex = "1"

2. 定义统计函数

在`counter.rs`文件中,我们定义一个名为`count_lines`的函数,该函数接收一个目录路径作为参数,并返回一个包含统计结果的`HashMap`。

rust
use std::collections::HashMap;
use std::fs::{self, DirEntry};
use std::path::PathBuf;
use walkdir::WalkDir;

pub fn count_lines(dir_path: &str) -> HashMap<String, HashMap> {
let mut result = HashMap::new();
let mut dir_path = PathBuf::from(dir_path);

for entry in WalkDir::new(&dir_path).into_iter().filter_map(|e| e.ok()) {
let path = entry.path();
if path.is_dir() {
continue;
}

let file_extension = path.extension().and_then(|s| s.to_str()).unwrap_or("");
let mut language = match file_extension {
"rs" => "Rust",
_ => continue,
};

let mut dir = path.strip_prefix(&dir_path).unwrap_or(&path).to_string_lossy().to_string();
dir.pop(); // 移除最后一个字符(通常是/或)

result.entry(language.to_string()).or_insert_with(HashMap::new).entry(dir.to_string()).or_insert(0) += 1;
}

result
}

3. 主函数

在`main.rs`文件中,我们定义主函数,接收用户输入的目录路径,并调用`count_lines`函数进行统计。

rust
use std::env;

fn main() {
let args: Vec = env::args().collect();
if args.len() < 2 {
println!("Usage: {} ", args[0]);
return;
}

let dir_path = &args[1];
let result = count_lines(dir_path);

for (language, dirs) in result {
println!("{}:", language);
for (dir, count) in dirs {
println!(" {}: {}", dir, count);
}
}
}

性能优化

在上述实现中,我们使用了`walkdir`库来遍历目录,并使用`HashMap`来存储统计结果。以下是一些性能优化措施:

1. 并行处理:使用`rayon`库实现并行处理,提高遍历目录的速度。

rust
use rayon::prelude::;

fn count_lines(dir_path: &str) -> HashMap<String, HashMap> {
let mut result = HashMap::new();
let mut dir_path = PathBuf::from(dir_path);

let entries: Vec = WalkDir::new(&dir_path)
.into_iter()
.filter_map(|e| e.ok())
.collect();

entries.par_iter().for_each(|entry| {
let path = entry.path();
if path.is_dir() {
return;
}

let file_extension = path.extension().and_then(|s| s.to_str()).unwrap_or("");
let mut language = match file_extension {
"rs" => "Rust",
_ => return,
};

let mut dir = path.strip_prefix(&dir_path).unwrap_or(&path).to_string_lossy().to_string();
dir.pop(); // 移除最后一个字符(通常是/或)

result.entry(language.to_string()).or_insert_with(HashMap::new).entry(dir.to_string()).or_insert(0) += 1;
});

result
}

2. 缓存结果:对于频繁访问的目录,可以将统计结果缓存起来,避免重复计算。

3. 减少内存占用:在遍历目录时,尽量使用迭代器而不是将所有结果存储在内存中。

总结

本文介绍了使用Rust语言实现一个简单的代码行数统计工具的方法,并对其性能进行了优化。在实际应用中,可以根据需求对工具进行扩展,例如添加更多语言支持、输出格式化结果等。希望本文对您有所帮助。