Skip to content

Commit 49080fe

Browse files
authored
further performance improvements (#84)
- `make ci` for consistent builds in CI. - Adaptively run 386 builds in docker on laptop and bare in CI. - More flexible profiling in `Makefile`. - Detect memory allocation regressions. - Rework numerous functions to reduce copying. - Remove several unused functions. - Improve constant array lookups. - Use `arr[i%len(arr)]` to avoid bounds checks. - Pad to 2ⁿ to avoid weird `i%len(arr)` math. - Shrink some types for better packing. - Change flavor constants for more efficient bit calcs. - Optimise 128-bit divide by 10¹⁵ and 10¹⁶. - Optimise all `uint128T` operations to minimise copying. - Simplify and optimiser decimal unpacking. Split flavor unpack into a separate operation for earlier short-circuiting. - Remove `original` field from `decParts`. - Add `replayOnFail` for easier test replay. - Rename IO benchmarks for better grouping. - Faster `Add`, `Cmp` and `Mul`. - Much faster sqrt using table lookup. - Add `squareroot.decTest` suite.
1 parent 6ceca07 commit 49080fe

19 files changed

+3830
-3709
lines changed

.github/workflows/go.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ jobs:
2525
fi
2626
2727
- name: Test Basic
28-
run: go test -v -race ./...
28+
run: make ci
29+
env:
30+
GOTESTFLAGS: -race
2931

3032
- name: Test 32 bit system
3133
run: GOARCH=386 go test ./...

Makefile

+36-12
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
.PHONY: all
22
all: test-all build-linux lint
33

4+
.PHONY: ci
5+
ci: test-all no-allocs
46

57
.PHONY: test-all
6-
test-all: test test-debug test-32
8+
test-all: test test-32
79

810
.PHONY: test
911
test:
1012
go test $(GOTESTFLAGS)
11-
12-
.PHONY: test-debug
13-
test-debug:
1413
go test $(GOTESTFLAGS) -tags=decimal_debug
1514

1615
.PHONY: test-32
1716
test-32:
18-
$(DOCKERRUN) -e GOARCH=arm golang:1.23.0 go test $(GOTESTFLAGS)
17+
if [ "$(shell go env GOOS)" = "linux" ]; then \
18+
GOARCH=386 go test $(subst -race,,$(GOTESTFLAGS)); \
19+
else \
20+
$(DOCKERRUN) -e GOARCH=arm golang:1.23.0 go test $(GOTESTFLAGS); \
21+
fi
1922

2023
.PHONY: build-linux
2124
build-linux:
@@ -46,19 +49,17 @@ DOCKERRUN = docker run --rm \
4649
-v `go env GOCACHE`:/root/.cache/go-build \
4750
-v `go env GOMODCACHE`:/go/pkg/mod
4851

49-
5052
# Dependency on build-linux primes Go caches.
5153
.PHONY: lint
5254
lint: build-linux
5355
$(DOCKERRUN) golangci/golangci-lint:v1.60.1-alpine golangci-lint run
5456

55-
.PHONY: profile
56-
profile: cpu.prof
57+
%.pprof: %.prof
5758
go tool pprof -http=:8080 $<
5859

59-
.INTERMEDIATE: cpu.prof
60-
cpu.prof:
61-
go test -cpuprofile $@ -count=10 $(GOTESTFLAGS)
60+
.INTERMEDIATE: %.prof
61+
%.prof: $(wildcard *.go)
62+
go test -$*profile $@ -count=10 $(GOPROFILEFLAGS)
6263

6364
.PHONY: bench
6465
bench: bench.txt
@@ -72,4 +73,27 @@ bench.stat: bench.txt
7273
benchstat bench.old $< > $@ || (rm -f $@; false)
7374

7475
bench.txt: test
75-
go test -run=^$$ -bench=. -benchmem -count=10 $(GOTESTFLAGS) > $@ || (rm -f $@; false)
76+
go test -run=^$$ -bench=. -benchmem $(GOBENCHFLAGS) | tee $@ || (rm -f $@; false)
77+
78+
NOALLOC = \
79+
BenchmarkIODecimal64String2 \
80+
BenchmarkIODecimal64Append \
81+
BenchmarkDecimal64Abs \
82+
BenchmarkDecimal64Add \
83+
BenchmarkDecimal64Cmp \
84+
BenchmarkDecimal64Mul \
85+
BenchmarkFloat64Mul \
86+
BenchmarkDecimal64Quo \
87+
BenchmarkDecimal64Sqrt \
88+
BenchmarkDecimal64Sub
89+
90+
no-allocs:
91+
allocs=$$( \
92+
go test -run=^$$ -bench="^($$(echo $(NOALLOC) | sed 's/ /|/g'))$$" -benchmem $(GOBENCHFLAGS) | \
93+
awk '/^Benchmark/ {if ($$7 != "0") print}' \
94+
); \
95+
if [ -n "$$allocs" ]; then \
96+
echo "** alloc regression **"; \
97+
echo "$$allocs"; \
98+
false; \
99+
fi

0 commit comments

Comments
 (0)