Skip to content

Commit 085b5fc

Browse files
authored
benchmark (#209)
1 parent 8ea4ca3 commit 085b5fc

File tree

2 files changed

+60
-26
lines changed

2 files changed

+60
-26
lines changed

pmtiles/tile_id.go

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,51 +4,52 @@ import (
44
"math/bits"
55
)
66

7-
func rotate(n uint64, x *uint64, y *uint64, rx uint64, ry uint64) {
7+
func rotate(n uint32, x uint32, y uint32, rx uint32, ry uint32) (uint32, uint32) {
88
if ry == 0 {
9-
if rx == 1 {
10-
*x = n - 1 - *x
11-
*y = n - 1 - *y
9+
if rx != 0 {
10+
x = n - 1 - x
11+
y = n - 1 - y
1212
}
13-
*x, *y = *y, *x
13+
return y, x
1414
}
15+
return x, y
1516
}
1617

1718
// ZxyToID converts (Z,X,Y) tile coordinates to a Hilbert TileID.
1819
func ZxyToID(z uint8, x uint32, y uint32) uint64 {
19-
var acc uint64 = ((1 << (z * 2)) - 1) / 3
20-
var tx, ty uint64 = uint64(x), uint64(y)
21-
for a := int32(z - 1); a >= 0; a-- {
22-
var rx uint64 = (tx >> a) & 1
23-
var ry uint64 = (ty >> a) & 1
24-
var s uint64 = (1 << a)
25-
rotate(s, &tx, &ty, rx, ry)
26-
acc += s * s * ((3 * rx) ^ ry)
20+
var acc uint64 = (1<<(z*2) - 1) / 3
21+
n := uint32(z - 1)
22+
for s := uint32(1 << n); s > 0; s >>= 1 {
23+
var rx = s & x
24+
var ry = s & y
25+
acc += uint64((3*rx)^ry) << n
26+
x, y = rotate(s, x, y, rx, ry)
27+
n--
2728
}
2829
return acc
2930
}
3031

3132
// IDToZxy converts a Hilbert TileID to (Z,X,Y) tile coordinates.
3233
func IDToZxy(i uint64) (uint8, uint32, uint32) {
33-
var z uint8 = uint8((64 - bits.LeadingZeros64(3*i+1) - 1) / 2)
34-
var acc uint64 = (1<<(z*2) - 1) / 3
35-
var pos uint64 = i - acc
36-
var tx, ty uint64 = 0, 0
34+
var z = uint8(bits.Len64(3*i+1)-1) / 2
35+
var acc = (uint64(1)<<(z*2) - 1) / 3
36+
var t = i - acc
37+
var tx, ty uint32
3738
for a := uint8(0); a < z; a++ {
38-
var rx uint64 = (pos / 2) & 1
39-
var ry uint64 = (pos ^ rx) & 1
40-
var s uint64 = 1 << a
41-
rotate(s, &tx, &ty, rx, ry)
42-
tx += s * rx
43-
ty += s * ry
44-
pos /= 4
39+
var s = uint32(1) << a
40+
var rx = 1 & (uint32(t) >> 1)
41+
var ry = 1 & (uint32(t) ^ rx)
42+
tx, ty = rotate(s, tx, ty, rx, ry)
43+
tx += rx << a
44+
ty += ry << a
45+
t >>= 2
4546
}
46-
return z, uint32(tx), uint32(ty)
47+
return uint8(z), tx, ty
4748
}
4849

4950
// ParentID efficiently finds a parent Hilbert TileID without converting to (Z,X,Y).
5051
func ParentID(i uint64) uint64 {
51-
var z uint8 = uint8((64 - bits.LeadingZeros64(3*i+1) - 1) / 2)
52+
var z = uint8(64-bits.LeadingZeros64(3*i+1)-1) / 2
5253
var acc uint64 = (1<<(z*2) - 1) / 3
5354
var parentAcc uint64 = (1<<((z-1)*2) - 1) / 3
5455
return parentAcc + (i-acc)/4

pmtiles/tile_id_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,36 @@ func TestParent(t *testing.T) {
9898
assert.Equal(t, ZxyToID(18, 1, 500), ParentID(ZxyToID(19, 3, 1000)))
9999
assert.Equal(t, ZxyToID(18, 2, 500), ParentID(ZxyToID(19, 4, 1000)))
100100
}
101+
102+
func BenchmarkZxyToId(b *testing.B) {
103+
for n := 0; n < b.N; n++ {
104+
for z := uint8(0); z < 15; z += 1 {
105+
s := uint32(1 << z)
106+
for x := uint32(0); x < s; x += 13 {
107+
for y := uint32(0); y < s; y += 13 {
108+
_ = ZxyToID(z, x, y)
109+
}
110+
}
111+
}
112+
}
113+
}
114+
115+
func BenchmarkIdToZxy(b *testing.B) {
116+
end := ZxyToID(15, 0, 0)
117+
b.ResetTimer()
118+
for n := 0; n < b.N; n++ {
119+
for i := uint64(0); i < end; i += 13 {
120+
_, _, _ = IDToZxy(i)
121+
}
122+
}
123+
}
124+
125+
func BenchmarkParentId(b *testing.B) {
126+
end := ZxyToID(15, 0, 0)
127+
b.ResetTimer()
128+
for n := 0; n < b.N; n++ {
129+
for i := uint64(1); i < end; i += 13 {
130+
_ = ParentID(i)
131+
}
132+
}
133+
}

0 commit comments

Comments
 (0)