История изменений
Исправление zurg, (текущая версия) :
считать такие хеши надо максимально быстро,
Вот поэтому и надо брать раст, это ты чё там гадаешь по размеру ассемблерного выхлопа? Такое правильно так сравнивать:
const qspCRCTable: [u32; 256] =[ ... ];
fn qspCRC(data: &[u8]) -> i32 {
data.iter().fold(0, |crc, b| {
let tbl = qspCRCTable[(b ^ crc as u8) as usize];
(tbl as i32^crc>>8) ^ 0xD202EF8Du32 as i32
})
}
use std::time::*;
fn main() {
let len = 1_000_000_000;
let data: Vec<u8> = (0..len).map(|i| (i%256) as u8).collect();
let t0 = Instant::now();
let crc = qspCRC2(data.as_slice());
println!("time {} s", (t0.elapsed().as_micros() as f64)/1e6f64 );
println!("crc {}", crc);
}
time 2.112588 s
crc 2031280483
hyperfine ./crcr
Benchmark 1: ./crcr
Time (mean ± σ): 2.640 s ± 0.007 s [User: 2.163 s, System: 0.477 s]
Range (min … max): 2.630 s … 2.654 s 10 runs
int qspCRCTable[256] = {...};
int qspCRC(void *data, int len)
{
unsigned char *ptr;
int crc = 0;
ptr = (unsigned char *)data;
while (len--)
crc = (qspCRCTable[(crc & 0xFF) ^ *ptr++] ^ crc >> 8) ^ 0xD202EF8D;
return crc;
}
int main(void) {
int32_t len = 10000000;
uint8_t* data = (uint8_t*)malloc(len);
for(uint32_t i=0; i<len; i++) { data[i] = i%256; }
clock_t start_time = clock();
int crc = qspCRC(data, len);
double elapsed_time = (double)(clock() - start_time) / CLOCKS_PER_SEC;
printf("time %f s\n", elapsed_time);
printf("crc %i\n", crc);
}
time 2.113202 s
crc 2031280483
hyperfine ./crctst
Benchmark 1: ./crctst
Time (mean ± σ): 2.717 s ± 0.009 s [User: 2.243 s, System: 0.474 s]
Range (min … max): 2.705 s … 2.734 s 10 runs
hyperfine для оценки погрешности, короче разницы между llvm и gcc, и между раст и си для функции qspCRC в пределах погрешности нет.
Исходная версия zurg, :
считать такие хеши надо максимально быстро,
Вот поэтому и надо брать раст, это ты чё там гадаешь по размеру ассемблерного выхлопа?
const qspCRCTable: [u32; 256] =[ ... ];
fn qspCRC(data: &[u8]) -> i32 {
data.iter().fold(0, |crc, b| {
let tbl = qspCRCTable[(b ^ crc as u8) as usize];
(tbl as i32^crc>>8) ^ 0xD202EF8Du32 as i32
})
}
use std::time::*;
fn main() {
let len = 1_000_000_000;
let data: Vec<u8> = (0..len).map(|i| (i%256) as u8).collect();
let t0 = Instant::now();
let crc = qspCRC2(data.as_slice());
println!("time {} s", (t0.elapsed().as_micros() as f64)/1e6f64 );
println!("crc {}", crc);
}
time 2.112588 s
crc 2031280483
hyperfine ./crcr
Benchmark 1: ./crcr
Time (mean ± σ): 2.640 s ± 0.007 s [User: 2.163 s, System: 0.477 s]
Range (min … max): 2.630 s … 2.654 s 10 runs
int qspCRCTable[256] = {...};
int qspCRC(void *data, int len)
{
unsigned char *ptr;
int crc = 0;
ptr = (unsigned char *)data;
while (len--)
crc = (qspCRCTable[(crc & 0xFF) ^ *ptr++] ^ crc >> 8) ^ 0xD202EF8D;
return crc;
}
int main(void) {
int32_t len = 10000000;
uint8_t* data = (uint8_t*)malloc(len);
for(uint32_t i=0; i<len; i++) { data[i] = i%256; }
clock_t start_time = clock();
int crc = qspCRC(data, len);
double elapsed_time = (double)(clock() - start_time) / CLOCKS_PER_SEC;
printf("time %f s\n", elapsed_time);
printf("crc %i\n", crc);
}
time 2.113202 s
crc 2031280483
hyperfine ./crctst
Benchmark 1: ./crctst
Time (mean ± σ): 2.717 s ± 0.009 s [User: 2.243 s, System: 0.474 s]
Range (min … max): 2.705 s … 2.734 s 10 runs
hyperfine для оценки погрешности, короче разницы между llvm и gcc, и между раст и си для функции qspCRC в пределах погрешности нет.