Vectorize += for Symbols

This makes += ~8x faster, and encoding/decoding benchmarks ~15% faster
This commit is contained in:
Christopher Berner 2019-02-04 18:42:58 -08:00
parent 1abbfe845a
commit 208dff0152

@ -52,10 +52,44 @@ impl Symbol {
impl<'a> AddAssign<&'a Symbol> for Symbol {
fn add_assign(&mut self, other: &'a Symbol) {
assert_eq!(self.value.len(), other.value.len());
for i in 0..self.value.len() {
let self_ptr = self.value.as_mut_ptr() as *mut u64;
let other_ptr = other.value.as_ptr() as *const u64;
for i in 0..(self.value.len() / 8) {
unsafe {
*self_ptr.add(i) ^= *other_ptr.add(i);
}
}
let remainder = self.value.len() % 8;
for i in (self.value.len() - remainder)..self.value.len() {
unsafe {
*self.value.get_unchecked_mut(i) += other.value.get_unchecked(i);
}
}
}
}
#[cfg(test)]
mod tests {
extern crate rand;
use symbol::tests::rand::Rng;
use symbol::Symbol;
#[test]
fn add_assign() {
let symbol_size = 17;
let mut data1: Vec<u8> = vec![0; symbol_size];
let mut data2: Vec<u8> = vec![0; symbol_size];
let mut result: Vec<u8> = vec![0; symbol_size];
for i in 0..symbol_size {
data1[i] = rand::thread_rng().gen();
data2[i] = rand::thread_rng().gen();
result[i] = data1[i] ^ data2[i];
}
let mut symbol1 = Symbol::new(data1);
let symbol2 = Symbol::new(data2);
symbol1 += &symbol2;
assert_eq!(result, symbol1.bytes());
}
}