Skip to content

Commit

Permalink
chore(ci): enable overflow-checks in ci profile (databendlabs#16895)
Browse files Browse the repository at this point in the history
* chore(ci): enable overflow-checks  in ci profile

* update

* update

* update

* update

* update

* update

* update

* update
  • Loading branch information
sundy-li authored and dantengsky committed Nov 26, 2024
1 parent 6d7b1f1 commit d5b12e6
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 49 deletions.
18 changes: 10 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -353,22 +353,24 @@ result_large_err = "allow"
debug = 1
lto = "thin"
overflow-checks = false
incremental = false
opt-level = "s"
opt-level = "s" ## defaults to be 3
incremental = true

# codegen-units = 1 # Reduce number of codegen units to increase optimizations.
[profile.ci]
inherits = "release"
overflow-checks = true
incremental = false
debug-assertions = true

# [profile.release.package]
# arrow2 = { codegen-units = 4 }
# common-functions = { codegen-units = 16 }
# databend-query = { codegen-units = 4 }
# databend-binaries = { codegen-units = 4 }

[profile.dev]
split-debuginfo = "unpacked"
overflow-checks = false
# wait until https://github.com/rust-lang/rust/issues/100142 fixed
incremental = false
overflow-checks = true
# Report to https://github.com/rust-lang/rust/issues/100142 if incremental works well
incremental = true

[profile.dev.package]
addr2line = { opt-level = 3 }
Expand Down
50 changes: 20 additions & 30 deletions src/common/arrow/src/arrow/buffer/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ use crate::arrow::trusted_len::TrustedLen;
/// This crates' equivalent of [`std::vec::IntoIter`] for [`Buffer`].
#[derive(Debug, Clone)]
pub struct IntoIter<T: Copy> {
values: Buffer<T>,
index: usize,
end: usize,
buffer: Buffer<T>,
current: *const T,
end: *const T,
}

impl<T: Copy> IntoIter<T> {
/// Creates a new [`Buffer`]
#[inline]
pub fn new(values: Buffer<T>) -> Self {
let end = values.len();
pub fn new(buffer: Buffer<T>) -> Self {
let ptr = buffer.as_ptr();
let len = buffer.len();
Self {
values,
index: 0,
end,
current: ptr,
end: unsafe { ptr.add(len) },
buffer,
}
}
}
Expand All @@ -42,40 +42,30 @@ impl<T: Copy> Iterator for IntoIter<T> {

#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.index == self.end {
return None;
if self.current == self.end {
None
} else {
let value = unsafe { *self.current };
self.current = unsafe { self.current.add(1) };
Some(value)
}
let old = self.index;
self.index += 1;
Some(*unsafe { self.values.get_unchecked(old) })
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.end - self.index, Some(self.end - self.index))
}

#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let new_index = self.index + n;
if new_index > self.end {
self.index = self.end;
None
} else {
self.index = new_index;
self.next()
}
let len = unsafe { self.end.offset_from(self.current) } as usize;
(len, Some(len))
}
}

impl<T: Copy> DoubleEndedIterator for IntoIter<T> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
if self.index == self.end {
if self.current == self.end {
None
} else {
self.end -= 1;
Some(*unsafe { self.values.get_unchecked(self.end) })
self.end = unsafe { self.end.sub(1) };
Some(unsafe { *self.end })
}
}
}
Expand Down
239 changes: 239 additions & 0 deletions src/query/expression/benches/bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
// Copyright 2021 Datafuse Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate criterion;

use criterion::Criterion;
use databend_common_column::buffer::Buffer;
use databend_common_expression::arrow::deserialize_column;
use databend_common_expression::arrow::serialize_column;
use databend_common_expression::types::BinaryType;
use databend_common_expression::types::StringType;
use databend_common_expression::Column;
use databend_common_expression::DataBlock;
use databend_common_expression::FromData;
use rand::rngs::StdRng;
use rand::Rng;
use rand::SeedableRng;

fn bench(c: &mut Criterion) {
let mut group = c.benchmark_group("bench_kernels");

let mut rng = StdRng::seed_from_u64(0);
// concats
{
for length in [12, 20, 500] {
let (s, b) = generate_random_string_data(&mut rng, length);
let bin_col = (0..5).map(|_| BinaryType::from_data(b.clone()));
let str_col = (0..5).map(|_| StringType::from_data(s.clone()));

group.bench_function(format!("concat_string_offset/{length}"), |b| {
b.iter(|| Column::concat_columns(bin_col.clone()).unwrap())
});

group.bench_function(format!("concat_string_view/{length}"), |b| {
b.iter(|| Column::concat_columns(str_col.clone()).unwrap())
});
}
}

// take compact
{
for length in [12, 20, 500] {
let (s, b) = generate_random_string_data(&mut rng, length);
let block_bin = DataBlock::new_from_columns(vec![BinaryType::from_data(b.clone())]);
let block_view = DataBlock::new_from_columns(vec![StringType::from_data(s.clone())]);

let indices: Vec<(u32, u32)> = (0..s.len())
.filter(|x| x % 10 == 0)
.map(|x| (x as u32, 1000))
.collect();
let num_rows = indices.len() * 1000;

group.bench_function(format!("take_compact_string_offset/{length}"), |b| {
b.iter(|| {
block_bin
.take_compacted_indices(&indices, num_rows)
.unwrap()
})
});

group.bench_function(format!("take_compact_string_view/{length}"), |b| {
b.iter(|| {
block_view
.take_compacted_indices(&indices, num_rows)
.unwrap()
})
});
}
}

// IPC
// bench_kernels/serialize_string_offset/12
// time: [183.25 µs 183.49 µs 183.93 µs]
// Found 7 outliers among 100 measurements (7.00%)
// 3 (3.00%) high mild
// 4 (4.00%) high severe
// bench_kernels/serialize_string_view/12
// time: [415.25 µs 415.36 µs 415.47 µs]
// Found 6 outliers among 100 measurements (6.00%)
// 3 (3.00%) high mild
// 3 (3.00%) high severe
// bench_kernels/serialize_string_offset/20
// time: [195.09 µs 195.15 µs 195.23 µs]
// Found 6 outliers among 100 measurements (6.00%)
// 6 (6.00%) high mild
// bench_kernels/serialize_string_view/20
// time: [464.96 µs 465.08 µs 465.21 µs]
// Found 4 outliers among 100 measurements (4.00%)
// 4 (4.00%) high mild
// bench_kernels/serialize_string_offset/500
// time: [3.3092 ms 3.3139 ms 3.3194 ms]
// Found 2 outliers among 100 measurements (2.00%)
// 1 (1.00%) high mild
// 1 (1.00%) high severe
// bench_kernels/serialize_string_view/500
// time: [3.9254 ms 3.9303 ms 3.9366 ms]
// Found 9 outliers among 100 measurements (9.00%)
// 4 (4.00%) high mild
// 5 (5.00%) high severe

{
for length in [12, 20, 500] {
let (s, b) = generate_random_string_data(&mut rng, length);
let b_c = BinaryType::from_data(b.clone());
let s_c = StringType::from_data(s.clone());

group.bench_function(format!("serialize_string_offset/{length}"), |b| {
b.iter(|| {
let bs = serialize_column(&b_c);
deserialize_column(&bs).unwrap();
})
});

group.bench_function(format!("serialize_string_view/{length}"), |b| {
b.iter(|| {
let bs = serialize_column(&s_c);
deserialize_column(&bs).unwrap();
})
});
}
}

for length in [10240, 102400] {
let (left, right) = generate_random_int_data(&mut rng, length);

group.bench_function(format!("function_iterator_iterator_v1/{length}"), |b| {
b.iter(|| {
let left = left.clone();
let right = right.clone();

let _c = left
.into_iter()
.zip(right.into_iter())
.map(|(a, b)| a + b)
.collect::<Vec<i32>>();
})
});

group.bench_function(format!("function_iterator_iterator_v2/{length}"), |b| {
b.iter(|| {
let _c = left
.iter()
.cloned()
.zip(right.iter().cloned())
.map(|(a, b)| a + b)
.collect::<Vec<i32>>();
})
});

group.bench_function(
format!("function_buffer_index_unchecked_iterator/{length}"),
|b| {
b.iter(|| {
let _c = (0..length)
.map(|i| unsafe { left.get_unchecked(i) + right.get_unchecked(i) })
.collect::<Vec<i32>>();
})
},
);

group.bench_function(
format!("function_slice_index_unchecked_iterator/{length}"),
|b| {
b.iter(|| {
let left = left.as_slice();
let right = right.as_slice();

let _c = (0..length)
.map(|i| unsafe { left.get_unchecked(i) + right.get_unchecked(i) })
.collect::<Vec<i32>>();
})
},
);

let left_vec: Vec<_> = left.iter().cloned().collect();
let right_vec: Vec<_> = right.iter().cloned().collect();

group.bench_function(
format!("function_vec_index_unchecked_iterator/{length}"),
|b| {
b.iter(|| {
let _c = (0..length)
.map(|i| unsafe { left_vec.get_unchecked(i) + right_vec.get_unchecked(i) })
.collect::<Vec<i32>>();
})
},
);

group.bench_function(format!("function_buffer_index_iterator/{length}"), |b| {
b.iter(|| {
let _c = (0..length)
.map(|i| left[i] + right[i])
.collect::<Vec<i32>>();
})
});
}
}

criterion_group!(benches, bench);
criterion_main!(benches);

fn generate_random_string_data(rng: &mut StdRng, length: usize) -> (Vec<String>, Vec<Vec<u8>>) {
let iter_str: Vec<_> = (0..10000)
.map(|_| {
let random_string: String = (0..length)
.map(|_| {
// Generate a random character (ASCII printable characters)
rng.gen_range(32..=126) as u8 as char
})
.collect();
random_string
})
.collect();

let iter_binary: Vec<_> = iter_str
.iter()
.map(|x| x.clone().as_bytes().to_vec())
.collect();

(iter_str, iter_binary)
}

fn generate_random_int_data(rng: &mut StdRng, length: usize) -> (Buffer<i32>, Buffer<i32>) {
let s: Buffer<i32> = (0..length).map(|_| rng.gen_range(-1000..1000)).collect();
let b: Buffer<i32> = (0..length).map(|_| rng.gen_range(-1000..1000)).collect();
(s, b)
}
10 changes: 5 additions & 5 deletions src/query/expression/src/filter/like.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,13 +271,13 @@ fn find(mut haystack: &[u8], needle: &[u8]) -> Option<usize> {
return None;
}
// Inspired by fast_strstr (https://github.com/RaphaelJ/fast_strstr).
let mut checksum = 0;
let mut checksum: i64 = 0;
for i in 0..needle_len {
// # Safety
// `needle_len` <= haystack_len
unsafe {
checksum += haystack.get_unchecked(i);
checksum -= needle.get_unchecked(i);
checksum += *haystack.get_unchecked(i) as i64;
checksum -= *needle.get_unchecked(i) as i64;
}
}
let mut idx = 0;
Expand All @@ -298,8 +298,8 @@ fn find(mut haystack: &[u8], needle: &[u8]) -> Option<usize> {
// # Safety
// `idx` < `haystack_len` and `idx` + `needle_len` < `haystack_len`.
unsafe {
checksum -= haystack.get_unchecked(idx);
checksum += haystack.get_unchecked(idx + needle_len);
checksum -= *haystack.get_unchecked(idx) as i64;
checksum += *haystack.get_unchecked(idx + needle_len) as i64;
}
idx += 1;
}
Expand Down
Loading

0 comments on commit d5b12e6

Please sign in to comment.