-
Notifications
You must be signed in to change notification settings - Fork 877
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2136 from ninedraft/optimize-sanitize
Reduce SQL sanitizer allocations
- Loading branch information
Showing
6 changed files
with
387 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#!/usr/bin/env bash | ||
|
||
current_branch=$(git rev-parse --abbrev-ref HEAD) | ||
if [ "$current_branch" == "HEAD" ]; then | ||
current_branch=$(git rev-parse HEAD) | ||
fi | ||
|
||
restore_branch() { | ||
echo "Restoring original branch/commit: $current_branch" | ||
git checkout "$current_branch" | ||
} | ||
trap restore_branch EXIT | ||
|
||
# Check if there are uncommitted changes | ||
if ! git diff --quiet || ! git diff --cached --quiet; then | ||
echo "There are uncommitted changes. Please commit or stash them before running this script." | ||
exit 1 | ||
fi | ||
|
||
# Ensure that at least one commit argument is passed | ||
if [ "$#" -lt 1 ]; then | ||
echo "Usage: $0 <commit1> <commit2> ... <commitN>" | ||
exit 1 | ||
fi | ||
|
||
commits=("$@") | ||
benchmarks_dir=benchmarks | ||
|
||
if ! mkdir -p "${benchmarks_dir}"; then | ||
echo "Unable to create dir for benchmarks data" | ||
exit 1 | ||
fi | ||
|
||
# Benchmark results | ||
bench_files=() | ||
|
||
# Run benchmark for each listed commit | ||
for i in "${!commits[@]}"; do | ||
commit="${commits[i]}" | ||
git checkout "$commit" || { | ||
echo "Failed to checkout $commit" | ||
exit 1 | ||
} | ||
|
||
# Sanitized commmit message | ||
commit_message=$(git log -1 --pretty=format:"%s" | tr -c '[:alnum:]-_' '_') | ||
|
||
# Benchmark data will go there | ||
bench_file="${benchmarks_dir}/${i}_${commit_message}.bench" | ||
|
||
if ! go test -bench=. -count=10 >"$bench_file"; then | ||
echo "Benchmarking failed for commit $commit" | ||
exit 1 | ||
fi | ||
|
||
bench_files+=("$bench_file") | ||
done | ||
|
||
# go install golang.org/x/perf/cmd/benchstat[@latest] | ||
benchstat "${bench_files[@]}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// sanitize_benchmark_test.go | ||
package sanitize_test | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/jackc/pgx/v5/internal/sanitize" | ||
) | ||
|
||
var benchmarkSanitizeResult string | ||
|
||
const benchmarkQuery = "" + | ||
`SELECT * | ||
FROM "water_containers" | ||
WHERE NOT "id" = $1 -- int64 | ||
AND "tags" NOT IN $2 -- nil | ||
AND "volume" > $3 -- float64 | ||
AND "transportable" = $4 -- bool | ||
AND position($5 IN "sign") -- bytes | ||
AND "label" LIKE $6 -- string | ||
AND "created_at" > $7; -- time.Time` | ||
|
||
var benchmarkArgs = []any{ | ||
int64(12345), | ||
nil, | ||
float64(500), | ||
true, | ||
[]byte("8BADF00D"), | ||
"kombucha's han'dy awokowa", | ||
time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), | ||
} | ||
|
||
func BenchmarkSanitize(b *testing.B) { | ||
query, err := sanitize.NewQuery(benchmarkQuery) | ||
if err != nil { | ||
b.Fatalf("failed to create query: %v", err) | ||
} | ||
|
||
b.ResetTimer() | ||
b.ReportAllocs() | ||
|
||
for i := 0; i < b.N; i++ { | ||
benchmarkSanitizeResult, err = query.Sanitize(benchmarkArgs...) | ||
if err != nil { | ||
b.Fatalf("failed to sanitize query: %v", err) | ||
} | ||
} | ||
} | ||
|
||
var benchmarkNewSQLResult string | ||
|
||
func BenchmarkSanitizeSQL(b *testing.B) { | ||
b.ReportAllocs() | ||
var err error | ||
for i := 0; i < b.N; i++ { | ||
benchmarkNewSQLResult, err = sanitize.SanitizeSQL(benchmarkQuery, benchmarkArgs...) | ||
if err != nil { | ||
b.Fatalf("failed to sanitize SQL: %v", err) | ||
} | ||
} | ||
} |
Oops, something went wrong.