From 53429415e92d542b0fd4ac0c3acaa52a2116be89 Mon Sep 17 00:00:00 2001 From: sundyli <543950155@qq.com> Date: Mon, 28 Feb 2022 12:41:23 +0800 Subject: [PATCH] Fix --- .gitignore | 1 + src/compute/filter.rs | 43 ++++++++++++++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 39564fe2b50..c10f9e51df0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ target-tarpaulin venv lcov.info Cargo.lock +example.arrow fixtures settings.json dev/ diff --git a/src/compute/filter.rs b/src/compute/filter.rs index 2ccf4a01d38..2668a05ce77 100644 --- a/src/compute/filter.rs +++ b/src/compute/filter.rs @@ -1,5 +1,5 @@ //! Contains operators to filter arrays such as [`filter`]. -use std::ops::{Shl, Shr}; +use std::ops::Shr; use crate::array::growable::{make_growable, Growable}; use crate::bitmap::utils::{BitChunk, BitChunkIterExact, BitChunksExact}; @@ -32,9 +32,19 @@ where .zip(mask_chunks.by_ref()) .for_each(|(chunk, validity_chunk)| { let ones_iter = BitChunkOnes::new(validity_chunk); - for pos in ones_iter { - dst.write(chunk[pos]); - dst = dst.add(1); + + let (size, _) = ones_iter.size_hint(); + if size == T::Simd::LANES { + // Fast path: all lanes are set + unsafe { + std::ptr::copy(chunk.as_ptr(), dst, size); + dst = dst.add(size); + } + } else { + for pos in ones_iter { + dst.write(chunk[pos]); + dst = dst.add(1); + } } }); @@ -82,14 +92,25 @@ where .zip(mask_chunks.by_ref()) .for_each(|((chunk, validity_chunk), mask_chunk)| { let ones_iter = BitChunkOnes::new(mask_chunk); + let (size, _) = ones_iter.size_hint(); - for pos in ones_iter { - dst.write(chunk[pos]); - dst = dst.add(1); - new_validity.push( - (validity_chunk.shr(pos) & <<::Simd as NativeSimd>::Chunk>::one()) - > <<::Simd as NativeSimd>::Chunk>::zero(), - ); + if size == T::Simd::LANES { + // Fast path: all lanes are set + unsafe { + std::ptr::copy(chunk.as_ptr(), dst, size); + dst = dst.add(size); + new_validity.extend_from_slice(validity_chunk.to_ne_bytes().as_ref(), 0, size); + } + } else { + for pos in ones_iter { + dst.write(chunk[pos]); + dst = dst.add(1); + new_validity.push( + (validity_chunk.shr(pos) + & <<::Simd as NativeSimd>::Chunk>::one()) + > <<::Simd as NativeSimd>::Chunk>::zero(), + ); + } } });