From e4b848ebfa3b85255a95f9b380ee437e68674820 Mon Sep 17 00:00:00 2001 From: "Heres, Daniel" Date: Sun, 7 Nov 2021 22:05:11 +0100 Subject: [PATCH 1/5] Speedup binary bitwise ops --- benches/bitwise.rs | 2 +- src/bitmap/bitmap_ops.rs | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/benches/bitwise.rs b/benches/bitwise.rs index c91b5aad394..7597b15dd7b 100644 --- a/benches/bitwise.rs +++ b/benches/bitwise.rs @@ -1,4 +1,4 @@ -use std::ops::{BitOr, BitXor, Not}; +use std::ops::{BitAnd, BitOr, BitXor, Not}; use criterion::{criterion_group, criterion_main, Criterion}; use num_traits::NumCast; diff --git a/src/bitmap/bitmap_ops.rs b/src/bitmap/bitmap_ops.rs index 065ba0dcbd4..461b1ef2b23 100644 --- a/src/bitmap/bitmap_ops.rs +++ b/src/bitmap/bitmap_ops.rs @@ -1,6 +1,6 @@ use std::ops::{BitAnd, BitOr, BitXor, Not}; -use crate::buffer::MutableBuffer; +use crate::{bitmap::utils::BitChunk, buffer::MutableBuffer}; use super::{ utils::{BitChunkIterExact, BitChunksExact}, @@ -85,18 +85,22 @@ where assert_eq!(lhs.len(), rhs.len()); let mut lhs_chunks = lhs.chunks(); let mut rhs_chunks = rhs.chunks(); + let rem_lhs = lhs_chunks.remainder(); + let rem_rhs = rhs_chunks.remainder(); let chunks = lhs_chunks .by_ref() .zip(rhs_chunks.by_ref()) .map(|(left, right)| op(left, right)); - // Soundness: `BitChunks` is a trusted len iterator - let mut buffer = unsafe { MutableBuffer::from_chunk_iter_unchecked(chunks) }; - let remainder_bytes = lhs_chunks.remainder_len().saturating_add(7) / 8; - let rem = op(lhs_chunks.remainder(), rhs_chunks.remainder()); - let rem = &rem.to_ne_bytes()[..remainder_bytes]; - buffer.extend_from_slice(rem); + // Soundness: `BitChunks` is a trusted len iterator + let buffer = unsafe { + MutableBuffer::from_chunk_iter_unchecked(chunks.chain(std::iter::once( + BitChunk::from_ne_bytes( + op(rem_lhs, rem_rhs).to_ne_bytes(), + ), + ))) + }; let length = lhs.len(); From f12caca56f8cda1674649c5c9ac20384fe3d97b4 Mon Sep 17 00:00:00 2001 From: "Heres, Daniel" Date: Sun, 7 Nov 2021 22:15:30 +0100 Subject: [PATCH 2/5] Simplify --- src/bitmap/bitmap_ops.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/bitmap/bitmap_ops.rs b/src/bitmap/bitmap_ops.rs index 461b1ef2b23..a3fbf75b515 100644 --- a/src/bitmap/bitmap_ops.rs +++ b/src/bitmap/bitmap_ops.rs @@ -1,6 +1,6 @@ use std::ops::{BitAnd, BitOr, BitXor, Not}; -use crate::{bitmap::utils::BitChunk, buffer::MutableBuffer}; +use crate::buffer::MutableBuffer; use super::{ utils::{BitChunkIterExact, BitChunksExact}, @@ -95,11 +95,9 @@ where // Soundness: `BitChunks` is a trusted len iterator let buffer = unsafe { - MutableBuffer::from_chunk_iter_unchecked(chunks.chain(std::iter::once( - BitChunk::from_ne_bytes( - op(rem_lhs, rem_rhs).to_ne_bytes(), - ), - ))) + MutableBuffer::from_chunk_iter_unchecked( + chunks.chain(std::iter::once(op(rem_lhs, rem_rhs))), + ) }; let length = lhs.len(); From d9a3a2799a31bc8bdc4254f625896cbeb0637c08 Mon Sep 17 00:00:00 2001 From: "Heres, Daniel" Date: Sun, 7 Nov 2021 22:33:41 +0100 Subject: [PATCH 3/5] Implement changes for ternary,quaternary functions --- src/bitmap/bitmap_ops.rs | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/bitmap/bitmap_ops.rs b/src/bitmap/bitmap_ops.rs index a3fbf75b515..3f2a3347b2f 100644 --- a/src/bitmap/bitmap_ops.rs +++ b/src/bitmap/bitmap_ops.rs @@ -20,6 +20,11 @@ where let mut a3_chunks = a3.chunks(); let mut a4_chunks = a4.chunks(); + let rem_a1 = a1_chunks.remainder(); + let rem_a2 = a2_chunks.remainder(); + let rem_a3 = a3_chunks.remainder(); + let rem_a4 = a4_chunks.remainder(); + let chunks = a1_chunks .by_ref() .zip(a2_chunks.by_ref()) @@ -27,17 +32,11 @@ where .zip(a4_chunks.by_ref()) .map(|(((a1, a2), a3), a4)| op(a1, a2, a3, a4)); // Soundness: `BitChunks` is a trusted len iterator - let mut buffer = unsafe { MutableBuffer::from_chunk_iter_unchecked(chunks) }; - - let remainder_bytes = a1_chunks.remainder_len().saturating_add(7) / 8; - let rem = op( - a1_chunks.remainder(), - a2_chunks.remainder(), - a3_chunks.remainder(), - a4_chunks.remainder(), - ); - let rem = &rem.to_ne_bytes()[..remainder_bytes]; - buffer.extend_from_slice(rem); + let buffer = unsafe { + MutableBuffer::from_chunk_iter_unchecked( + chunks.chain(std::iter::once(op(rem_a1, rem_a2, rem_a3, rem_a4))), + ) + }; let length = a1.len(); @@ -55,22 +54,21 @@ where let mut a2_chunks = a2.chunks(); let mut a3_chunks = a3.chunks(); + let rem_a1 = a1_chunks.remainder(); + let rem_a2 = a2_chunks.remainder(); + let rem_a3 = a3_chunks.remainder(); + let chunks = a1_chunks .by_ref() .zip(a2_chunks.by_ref()) .zip(a3_chunks.by_ref()) .map(|((a1, a2), a3)| op(a1, a2, a3)); // Soundness: `BitChunks` is a trusted len iterator - let mut buffer = unsafe { MutableBuffer::from_chunk_iter_unchecked(chunks) }; - - let remainder_bytes = a1_chunks.remainder_len().saturating_add(7) / 8; - let rem = op( - a1_chunks.remainder(), - a2_chunks.remainder(), - a3_chunks.remainder(), - ); - let rem = &rem.to_ne_bytes()[..remainder_bytes]; - buffer.extend_from_slice(rem); + let buffer = unsafe { + MutableBuffer::from_chunk_iter_unchecked( + chunks.chain(std::iter::once(op(rem_a1, rem_a2, rem_a3))), + ) + }; let length = a1.len(); From f7f9e4b04930598e090453badf59e86a286d0d8b Mon Sep 17 00:00:00 2001 From: "Heres, Daniel" Date: Sun, 7 Nov 2021 22:38:40 +0100 Subject: [PATCH 4/5] Simplify --- src/bitmap/bitmap_ops.rs | 58 ++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/src/bitmap/bitmap_ops.rs b/src/bitmap/bitmap_ops.rs index 3f2a3347b2f..956df787d7b 100644 --- a/src/bitmap/bitmap_ops.rs +++ b/src/bitmap/bitmap_ops.rs @@ -15,10 +15,10 @@ where assert_eq!(a1.len(), a2.len()); assert_eq!(a1.len(), a3.len()); assert_eq!(a1.len(), a4.len()); - let mut a1_chunks = a1.chunks(); - let mut a2_chunks = a2.chunks(); - let mut a3_chunks = a3.chunks(); - let mut a4_chunks = a4.chunks(); + let a1_chunks = a1.chunks(); + let a2_chunks = a2.chunks(); + let a3_chunks = a3.chunks(); + let a4_chunks = a4.chunks(); let rem_a1 = a1_chunks.remainder(); let rem_a2 = a2_chunks.remainder(); @@ -26,17 +26,13 @@ where let rem_a4 = a4_chunks.remainder(); let chunks = a1_chunks - .by_ref() - .zip(a2_chunks.by_ref()) - .zip(a3_chunks.by_ref()) - .zip(a4_chunks.by_ref()) + .zip(a2_chunks) + .zip(a3_chunks) + .zip(a4_chunks) .map(|(((a1, a2), a3), a4)| op(a1, a2, a3, a4)); - // Soundness: `BitChunks` is a trusted len iterator - let buffer = unsafe { - MutableBuffer::from_chunk_iter_unchecked( - chunks.chain(std::iter::once(op(rem_a1, rem_a2, rem_a3, rem_a4))), - ) - }; + let buffer = MutableBuffer::from_chunk_iter( + chunks.chain(std::iter::once(op(rem_a1, rem_a2, rem_a3, rem_a4))), + ); let length = a1.len(); @@ -50,25 +46,21 @@ where { assert_eq!(a1.len(), a2.len()); assert_eq!(a1.len(), a3.len()); - let mut a1_chunks = a1.chunks(); - let mut a2_chunks = a2.chunks(); - let mut a3_chunks = a3.chunks(); + let a1_chunks = a1.chunks(); + let a2_chunks = a2.chunks(); + let a3_chunks = a3.chunks(); let rem_a1 = a1_chunks.remainder(); let rem_a2 = a2_chunks.remainder(); let rem_a3 = a3_chunks.remainder(); let chunks = a1_chunks - .by_ref() - .zip(a2_chunks.by_ref()) - .zip(a3_chunks.by_ref()) + .zip(a2_chunks) + .zip(a3_chunks) .map(|((a1, a2), a3)| op(a1, a2, a3)); - // Soundness: `BitChunks` is a trusted len iterator - let buffer = unsafe { - MutableBuffer::from_chunk_iter_unchecked( - chunks.chain(std::iter::once(op(rem_a1, rem_a2, rem_a3))), - ) - }; + + let buffer = + MutableBuffer::from_chunk_iter(chunks.chain(std::iter::once(op(rem_a1, rem_a2, rem_a3)))); let length = a1.len(); @@ -81,22 +73,18 @@ where F: Fn(u64, u64) -> u64, { assert_eq!(lhs.len(), rhs.len()); - let mut lhs_chunks = lhs.chunks(); - let mut rhs_chunks = rhs.chunks(); + let lhs_chunks = lhs.chunks(); + let rhs_chunks = rhs.chunks(); let rem_lhs = lhs_chunks.remainder(); let rem_rhs = rhs_chunks.remainder(); let chunks = lhs_chunks - .by_ref() - .zip(rhs_chunks.by_ref()) + .zip(rhs_chunks) .map(|(left, right)| op(left, right)); // Soundness: `BitChunks` is a trusted len iterator - let buffer = unsafe { - MutableBuffer::from_chunk_iter_unchecked( - chunks.chain(std::iter::once(op(rem_lhs, rem_rhs))), - ) - }; + let buffer = + MutableBuffer::from_chunk_iter(chunks.chain(std::iter::once(op(rem_lhs, rem_rhs)))); let length = lhs.len(); From e68cda878cb74d47d8b62c2e86165c22129fd743 Mon Sep 17 00:00:00 2001 From: "Heres, Daniel" Date: Sun, 7 Nov 2021 22:39:27 +0100 Subject: [PATCH 5/5] Remove comment --- src/bitmap/bitmap_ops.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bitmap/bitmap_ops.rs b/src/bitmap/bitmap_ops.rs index 956df787d7b..28584d3c6fa 100644 --- a/src/bitmap/bitmap_ops.rs +++ b/src/bitmap/bitmap_ops.rs @@ -82,7 +82,6 @@ where .zip(rhs_chunks) .map(|(left, right)| op(left, right)); - // Soundness: `BitChunks` is a trusted len iterator let buffer = MutableBuffer::from_chunk_iter(chunks.chain(std::iter::once(op(rem_lhs, rem_rhs))));