Commit 33c53fe
authored
Optimize format number implementation (#14586)
### Description
Contributes to #14588.
This change optimizes the implementation of `format_number` originally
introduced in #9281. The
optimizations were found by Claude after it was tasked with optimizing
this implementation against microbenchmarks.
The optimizations are as follows:
- Use a scalar "," separator with the [scalar stringConcatenate
API](https://docs.rapids.ai/api/cudf-java/legacy/ai/rapids/cudf/columnvector#stringConcatenate(ai.rapids.cudf.Scalar,ai.rapids.cudf.Scalar,ai.rapids.cudf.ColumnView%5B%5D))
instead of allocating a full column.
- Use numeric sign detection by casting to float, rather than a string
conversion + string pattern match to look for a negative sign.
- Use a small `signCol` that is conditionally prepended to negative
numbers, instead of allocating a fully copy of the column with "-"
prepended.
#### Performance
Note that this operator does not appear in NDS/NDS-H, so I have the
following microbenchmarks for a targeted performance diff.
Generated data:
```bash
cat << 'EOF' | SPARK_HOME=/opt/spark-3.5.5 /opt/spark-3.5.5/bin/spark-shell \
--jars datagen/target/datagen_2.12-26.06.0-SNAPSHOT-spark355.jar \
--master "local[*]"
import org.apache.spark.sql.tests.datagen._
val types = Seq("long", "int", "short", "byte", "DECIMAL(38,10)")
for (t <- types) {
DBGen().addTable("data", s"a $t", 10000000)
.toDF(spark).write.mode("overwrite")
.parquet(s"/tmp/format_number_bench/${t.replaceAll("[^a-zA-Z0-9]", "_")}")
}
println("done")
:quit
EOF
```
Benchmark runs:
```bash
cat << 'EOF' | SPARK_HOME=/opt/spark-3.5.5 /opt/spark-3.5.5/bin/spark-shell \
--jars $PLUGIN_JAR \
--conf spark.plugins=com.nvidia.spark.SQLPlugin \
--master "local[*]"
val types = Seq(
("long", "/tmp/format_number_bench/long"),
("int", "/tmp/format_number_bench/int"),
("short", "/tmp/format_number_bench/short"),
("byte", "/tmp/format_number_bench/byte"),
("decimal", "/tmp/format_number_bench/DECIMAL_38_10_")
)
for ((name, path) <- types) {
val df = spark.read.parquet(path)
// warmup
df.selectExpr("COUNT(format_number(a, 0))", "COUNT(format_number(a, 5))").collect()
df.selectExpr("COUNT(format_number(a, 0))", "COUNT(format_number(a, 5))").collect()
// timed
for (i <- 1 to 3) {
print(s"${name}_run${i}: ")
spark.time(df.selectExpr("COUNT(format_number(a, 0))", "COUNT(format_number(a, 5))").collect())
}
}
:quit
EOF
```
Results:
| dtype | main | this change | speedup |
|-----------|-----------------|-----------|---------|
| long | 540 ms | 380 ms | **1.42x** |
| int | 362 ms | 285 ms | **1.27x** |
| short | 378 ms | 238 ms | **1.59x** |
| byte | 244 ms | 186 ms | **1.31x** |
| decimal(38,10) | 921 ms | 551 ms | **1.67x** |
### Checklists
Documentation
- [ ] Updated for new or modified user-facing features or behaviors
- [X] No user-facing change
Testing
- [ ] Added or modified tests to cover new code paths
- [X] Covered by existing tests
- [ ] Not required
Performance
- [X] Tests ran and results are added in the PR description
- [ ] Issue filed with a link in the PR description
- [ ] Not required
---------
Signed-off-by: Rishi Chandra <rishic@nvidia.com>1 parent ef71f42 commit 33c53fe
1 file changed
Lines changed: 77 additions & 60 deletions
Lines changed: 77 additions & 60 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2383 | 2383 | | |
2384 | 2384 | | |
2385 | 2385 | | |
2386 | | - | |
2387 | | - | |
2388 | | - | |
2389 | | - | |
2390 | | - | |
2391 | | - | |
2392 | | - | |
2393 | | - | |
2394 | 2386 | | |
2395 | 2387 | | |
2396 | 2388 | | |
| |||
2406 | 2398 | | |
2407 | 2399 | | |
2408 | 2400 | | |
2409 | | - | |
2410 | | - | |
2411 | | - | |
2412 | | - | |
2413 | | - | |
| 2401 | + | |
| 2402 | + | |
| 2403 | + | |
| 2404 | + | |
| 2405 | + | |
2414 | 2406 | | |
2415 | 2407 | | |
2416 | | - | |
2417 | | - | |
2418 | | - | |
2419 | | - | |
2420 | | - | |
| 2408 | + | |
| 2409 | + | |
| 2410 | + | |
| 2411 | + | |
| 2412 | + | |
| 2413 | + | |
| 2414 | + | |
| 2415 | + | |
2421 | 2416 | | |
2422 | 2417 | | |
2423 | 2418 | | |
| |||
2426 | 2421 | | |
2427 | 2422 | | |
2428 | 2423 | | |
2429 | | - | |
2430 | | - | |
2431 | | - | |
2432 | | - | |
2433 | | - | |
2434 | | - | |
2435 | | - | |
2436 | | - | |
2437 | | - | |
2438 | | - | |
2439 | | - | |
2440 | | - | |
2441 | | - | |
2442 | | - | |
2443 | | - | |
| 2424 | + | |
| 2425 | + | |
| 2426 | + | |
| 2427 | + | |
| 2428 | + | |
| 2429 | + | |
| 2430 | + | |
| 2431 | + | |
| 2432 | + | |
| 2433 | + | |
| 2434 | + | |
| 2435 | + | |
| 2436 | + | |
| 2437 | + | |
| 2438 | + | |
| 2439 | + | |
| 2440 | + | |
| 2441 | + | |
| 2442 | + | |
| 2443 | + | |
| 2444 | + | |
| 2445 | + | |
| 2446 | + | |
2444 | 2447 | | |
2445 | | - | |
2446 | | - | |
2447 | | - | |
2448 | | - | |
2449 | | - | |
2450 | | - | |
2451 | | - | |
| 2448 | + | |
| 2449 | + | |
| 2450 | + | |
| 2451 | + | |
2452 | 2452 | | |
2453 | 2453 | | |
2454 | 2454 | | |
2455 | 2455 | | |
2456 | 2456 | | |
2457 | | - | |
2458 | | - | |
2459 | | - | |
2460 | | - | |
2461 | | - | |
2462 | | - | |
2463 | | - | |
2464 | | - | |
2465 | | - | |
2466 | | - | |
2467 | | - | |
| 2457 | + | |
| 2458 | + | |
| 2459 | + | |
| 2460 | + | |
| 2461 | + | |
| 2462 | + | |
| 2463 | + | |
| 2464 | + | |
| 2465 | + | |
| 2466 | + | |
| 2467 | + | |
| 2468 | + | |
| 2469 | + | |
| 2470 | + | |
| 2471 | + | |
| 2472 | + | |
| 2473 | + | |
| 2474 | + | |
| 2475 | + | |
| 2476 | + | |
| 2477 | + | |
| 2478 | + | |
| 2479 | + | |
| 2480 | + | |
| 2481 | + | |
| 2482 | + | |
| 2483 | + | |
| 2484 | + | |
| 2485 | + | |
| 2486 | + | |
| 2487 | + | |
2468 | 2488 | | |
2469 | | - | |
2470 | 2489 | | |
2471 | 2490 | | |
2472 | | - | |
| 2491 | + | |
2473 | 2492 | | |
2474 | 2493 | | |
2475 | | - | |
2476 | | - | |
2477 | | - | |
| 2494 | + | |
| 2495 | + | |
| 2496 | + | |
2478 | 2497 | | |
2479 | 2498 | | |
2480 | | - | |
| 2499 | + | |
2481 | 2500 | | |
2482 | 2501 | | |
2483 | 2502 | | |
2484 | | - | |
2485 | | - | |
| 2503 | + | |
2486 | 2504 | | |
2487 | | - | |
2488 | 2505 | | |
2489 | 2506 | | |
2490 | 2507 | | |
| |||
0 commit comments