🤖

Rustで自分用ツールを書きつつ慣れていく(クロック周波数編)の続き

に公開

※ これは Rustで自分用ツールを書きつつ慣れていく(クロック周波数編)の続きになります。

正規表現を何とかしよう

cpu情報を持つディレクトリを検出するために、前回のコードでは正規表現モジュール(regex)を用いてましたが、 cpu[0-9]+ の解析を動的に行う必要があるためバイナリが肥大化することになってしまいます。使わずにすむ方法として、 /sys/devices/system/cpu/present を使って対応するという方法を考えていたのですが、 num_cpusというものに気づいてしまい、流されてしまいました。

crate.io: num_cpus

これでCPU数を確認したら、各ディレクトリのscaling_cur_freqを読み出していく流れに持ち込めば良いのでサクッと記述できます。
当初はCPU IDと周波数で構造体を組んでみたりしましたが、IDは使わないので Vec<u32> でクロックを入れるだけにして、イテレータからのfold()で足し込む形にしました。

use std::{fs, io::Read};

const BASEDIR: &str = "/sys/devices/system/cpu";

fn main() {
    let cpus = get_clock();
    let sum = cpus.iter().fold(0, |sum, cpu| sum + cpu);
    println!("{:.2}GHz", (sum / cpus.len() as u32) as f32 / 1000.0 as f32);
}

fn get_clock() -> Vec<u32> {
    (0..num_cpus::get())
        .into_iter()
        .map(|no| {
            let filename = format!("{}/cpu{}/cpufreq/scaling_cur_freq", BASEDIR, no);
            let mut file = fs::File::open(filename).unwrap();
            let mut buf = String::new();
            file.read_to_string(&mut buf).unwrap();
            buf.trim().to_owned().parse::<u32>().unwrap() / 1000
        })
        .collect()
}

main()に関してはすごくシンプルになった気がします。が、 as u32とか as f32とかがなんか冗長ですよね。
なんとかならないかな…

とりあえずリファクタリングできそうな所は?

ChatGPT先生に聞いたら、fold()しないでsum()すりゃええやんと言われてしまいました。

    let sum: u32 = cpus.iter().sum();

あとはできればasの利用を減らすことですね…

Discussion