1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use std::time;
use std::time::Instant;

use rand::{Rng, SeedableRng};

#[derive(Debug, Default)]
pub struct RAMResult {
    /// 内存大小
    pub mem_size: u64,
    /// 顺序写时间, 单位: s
    pub seq_write: f64,
    /// 顺序读时间, 单位: s
    pub seq_read: f64,
    /// 随机写时间, 单位: s
    pub rand_write: f64,
    /// 随机读时间, 单位: s
    pub rand_read: f64,
}

/// RAM 读写速度测试
pub struct RAMBench {
    /// memory 数据
    pub mem: Vec<u8>,
}

impl RAMBench {
    /// 创建一个新的 RAMBench 测试
    /// `mem_size` 单位为: 128MB
    pub fn new(mem_size: usize) -> Self {
        Self {
            mem: Vec::with_capacity(mem_size * 128 * 1024 * 1024),
        }
    }

    /// 运行一次性能测试
    pub fn run_bench(&mut self) -> RAMResult {
        let mut result = RAMResult::default();

        result.mem_size = self.mem.capacity() as u64;
        result.seq_write = self.seq_write_data().as_secs_f64();
        result.seq_read = self.seq_read_data().0.as_secs_f64();
        result.rand_write = self.rand_write_data().as_secs_f64();
        result.rand_read = self.rand_read_data().0.as_secs_f64();

        result
    }

    #[inline(never)]
    /// 随机写内存数据
    pub fn rand_write_data(&mut self) -> time::Duration {
        self.mem.truncate(0);

        let mem_size = self.mem.capacity();

        let gen_position_time = crate::shared::gen_n_usize_range_random_time(mem_size, mem_size);
        let gen_value_time = crate::shared::gen_n_u8_random_time(mem_size);

        let mut rng = rand::rngs::SmallRng::from_entropy();

        let ptr = self.mem.as_mut_ptr();

        let start_time = time::Instant::now();
        for _ in 0..mem_size {
            let position = rng.gen_range(0..mem_size);
            let value: u8 = rng.gen();
            unsafe {
                ptr.add(position).write(value);
            }
        }
        Instant::now() - start_time - gen_position_time - gen_value_time
    }

    #[inline(never)]
    /// 内存随机读取数据
    pub fn rand_read_data(&mut self) -> (time::Duration, u8) {
        self.mem.truncate(0);

        let ptr = self.mem.as_mut_ptr();
        let mem_size = self.mem.capacity();

        let gen_position_time = crate::shared::gen_n_usize_range_random_time(mem_size, mem_size);

        let mut rng = rand::rngs::SmallRng::from_entropy();

        let mut r = 0u8;
        let start_time = time::Instant::now();
        for _ in 0..mem_size {
            let position = rng.gen_range(0..mem_size);
            unsafe { r += ptr.add(position).read() };
        }
        (Instant::now() - start_time - gen_position_time, r)
    }

    /// 顺序写内存数据
    #[inline(never)]
    pub fn seq_write_data(&mut self) -> time::Duration {
        self.mem.truncate(0);

        let gen_time = crate::shared::gen_n_u8_random_time(self.mem.capacity());

        let mut rng = rand::rngs::SmallRng::from_entropy();

        let ptr = self.mem.as_mut_ptr();
        let mem_size = self.mem.capacity();

        let start_time = time::Instant::now();
        for i in 0..mem_size {
            let v: u8 = rng.gen();
            unsafe {
                ptr.add(i).write(v);
            }
        }
        Instant::now() - start_time - gen_time
    }

    /// 顺序读 数据
    #[inline(never)]
    pub fn seq_read_data(&mut self) -> (time::Duration, u8) {
        self.mem.truncate(0);

        let ptr = self.mem.as_mut_ptr();
        let mem_size = self.mem.capacity();

        let mut r = 0u8;
        let start_time = time::Instant::now();
        for i in 0..mem_size {
            let v = unsafe { ptr.add(i).read() };
            r += v;
        }
        (Instant::now() - start_time, r)
    }

    #[inline(never)]
    /// 随机生成 `n` 个 u8 类型的数据,并且计算和使用的时间
    pub fn add_n_random_time(n: usize) -> (time::Duration, u8) {
        let gen_time = crate::shared::gen_n_u8_random_time(n);

        let mut rng = rand::rngs::SmallRng::from_entropy();
        let mut r = 0u8;

        let start_time = time::Instant::now();
        for _ in 0..n {
            let v: u8 = rng.gen();
            r += v;
        }
        (Instant::now() - start_time - gen_time, r)
    }
}

#[test]
pub fn test_seq_write_ram() {
    let mut ram = RAMBench::new(1);
    let use_time = ram.seq_write_data();
    println!("use time: {:?}", use_time);
}