连续执行 10 次 (200×200 + 200×200) × 200×100 矩阵运算,比较仓颉和 Rust 的性能

仓颉和Rust分别以普通模式和发布模式编译各运行5次

因为cangjie没有发布模式,所以我手动模拟发布模式的优化:cjc -O2 src/main.cj -o main-release.exe

cangjie版本的代码如下:

import std.time.MonoTime

// 定义矩阵结构体
struct Matrix {
    let data: Array<Array<Int64>>

    // 构造函数:row 行,col 列,初始化为 0
    Matrix(let row: Int64, let col: Int64) {
        this.data = Array<Array<Int64>>(
            row,
            { _ => Array<Int64>(col, repeat: 0) }
        )
    }

    // 填充值
    func fill(val: Int64): Matrix {
        for (row in data) {
            for (i in 0..row.size) {
                row[i] = val
            }
        }
        this
    }

    // 矩阵加法
    public operator func +(that: Matrix): Matrix {
        if (data.size != that.data.size || data[0].size != that.data[0].size) {
            throw Exception("Matrix dimensions mismatch for addition")
        }
        let result = Matrix(data.size, data[0].size)
        for (y in 0..data.size) {
            for (x in 0..data[y].size) {
                result.data[y][x] = data[y][x] + that.data[y][x]
            }
        }
        result
    }

    // 矩阵乘法
    public operator func *(that: Matrix): Matrix {
        if (data[0].size != that.data.size) {
            throw Exception("Matrix dimensions mismatch for multiplication")
        }
        let rows = data.size
        let cols = that.data[0].size
        let inner = data[0].size
        let result = Matrix(rows, cols)
        for (y in 0..rows) {
            for (x in 0..cols) {
                var sum: Int64 = 0
                for (k in 0..inner) {
                    sum += data[y][k] * that.data[k][x]
                }
                result.data[y][x] = sum
            }
        }
        result
    }
}

// 主函数
main() {
    let start = MonoTime.now()

    // 执行 10 次计算(避免单次抖动)
    for (_ in 1..11) {
        let a = Matrix(200, 200).fill(3)
        let b = Matrix(200, 200).fill(4)
        let c = Matrix(200, 100).fill(5)
        let _ = (a + b) * c  // 计算但不输出
    }

    let duration = (MonoTime.now() - start).toMilliseconds()
    println("耗时(cangjie): ${duration} ms")
} 

Rust版本的代码如下:

use std::time::Instant;

#[derive(Debug, Clone)]
struct Matrix {
    data: Vec<Vec<i64>>,
}

impl Matrix {
    // 构造函数:rows 行,cols 列,初始化为 0
    fn new(rows: usize, cols: usize) -> Self {
        let data = vec![vec![0i64; cols]; rows];
        Matrix { data }
    }

    // 填充值
    fn fill(mut self, val: i64) -> Self {
        for row in &mut self.data {
            for elem in row {
                *elem = val;
            }
        }
        self
    }
}

// 实现加法:Matrix + Matrix
impl std::ops::Add for Matrix {
    type Output = Matrix;

    fn add(self, other: Self) -> Self::Output {
        if self.data.len() != other.data.len()
            || (!self.data.is_empty() && self.data[0].len() != other.data[0].len())
        {
            panic!("Matrix dimensions mismatch for addition");
        }

        let rows = self.data.len();
        let cols = if rows > 0 { self.data[0].len() } else { 0 };
        let mut result = Matrix::new(rows, cols);

        for i in 0..rows {
            for j in 0..cols {
                result.data[i][j] = self.data[i][j] + other.data[i][j];
            }
        }
        result
    }
}

// 实现乘法:Matrix * Matrix
impl std::ops::Mul for Matrix {
    type Output = Matrix;

    fn mul(self, other: Self) -> Self::Output {
        if self.data.is_empty()
            || other.data.is_empty()
            || self.data[0].len() != other.data.len()
        {
            panic!("Matrix dimensions mismatch for multiplication");
        }

        let rows = self.data.len();
        let cols = other.data[0].len();
        let inner = self.data[0].len();

        let mut result = Matrix::new(rows, cols);

        for i in 0..rows {
            for j in 0..cols {
                let mut sum = 0i64;
                for k in 0..inner {
                    sum += self.data[i][k] * other.data[k][j];
                }
                result.data[i][j] = sum;
            }
        }
        result
    }
}

fn main() {
    let start = Instant::now();

    // 执行 10 次计算
    for _ in 0..10 {
        let a = Matrix::new(200, 200).fill(3);
        let b = Matrix::new(200, 200).fill(4);
        let c = Matrix::new(200, 100).fill(5);

        let _result = (a + b) * c; // 计算但不输出
    }

    let duration = start.elapsed().as_millis();
    println!("耗时(Rust): {} ms", duration);
}

对比结果如下:

仓颉 Rust
普通模式 在这里插入图片描述 在这里插入图片描述
发布模式 在这里插入图片描述 在这里插入图片描述

总结:

  • 在普通模式下,Rust的性能大约是仓颉的2.43倍
  • 在发布模式下,Rust的性能大约是仓颉的2.2倍
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐