-
Notifications
You must be signed in to change notification settings - Fork 1.9k
perf: Optimize trunc scalar performance #19788
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| match &args.args[1] { | ||
| ColumnarValue::Scalar(Int64(Some(p))) => *p, | ||
| ColumnarValue::Scalar(Int64(None)) => { | ||
| return Ok(ColumnarValue::Scalar(ScalarValue::Float64(None))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should check the scalar type to decide whether to return Float64 or Float32
|
|
||
| fn compute_truncate32(x: f32, y: i64) -> f32 { | ||
| let factor = 10.0_f32.powi(y as i32); | ||
| (x * factor).round() / factor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not introduced in this PR but why f32::round() is used here instead of f32::trunc() ?
Same for f64 below.
fn main() {
let factor = 10_f64;
let r = (3.76_f64 * factor).round() / factor;
let t = (3.76_f64 * factor).trunc() / factor;
println!("round: {r}\ntrunc: {t}");
}prints:
round: 3.8
trunc: 3.7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it does seem like a bug. I will file an issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filed #19793
| }; | ||
|
|
||
| match scalar { | ||
| ScalarValue::Float64(v) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fast path for ScalarValue::Null too ?!
| ScalarValue::Float64(v) => { | ||
| let result = v.map(|x| { | ||
| if precision == 0 { | ||
| if x == 0.0 { 0.0 } else { x.trunc() } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if x == 0.0 { 0.0 } else { x.trunc() } | |
| x.trunc() |
| ScalarValue::Float32(v) => { | ||
| let result = v.map(|x| { | ||
| if precision == 0 { | ||
| if x == 0.0 { 0.0 } else { x.trunc() } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if x == 0.0 { 0.0 } else { x.trunc() } | |
| x.trunc() |
| )]; | ||
| let scalar_arg_fields = vec![Field::new("a", DataType::Float64, false).into()]; | ||
| let scalar_return_field = Field::new("f", DataType::Float64, false).into(); | ||
| let config_options = Arc::new(ConfigOptions::default()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This variable shadows the same one from line 40
|
Thanks for the feedback @martin-g, incorporated the changes. |
| return make_scalar_function(trunc, vec![])(&args.args); | ||
| } | ||
| None => Some(0), // default precision | ||
| _ => Some(0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This catch all arm should return an internal error, unless theres a case I'm missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it should. Made changes
Co-authored-by: Jeffrey Vo <[email protected]>
Which issue does this PR close?
Rationale for this change
The current
truncimplementation always converts scalar inputs to arrays viamake_scalar_function, which introduces unnecessary overhead when processing single values.What changes are included in this PR?
truncfunction to process Float32/Float64 scalar inputs directlyAre these changes tested?
Yes all sqllogictest pass
Benchmark Results
Are there any user-facing changes?
No