Skip to content
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

[gcs] HashMatchAny: faster filter matches for large queries #122

Merged
merged 3 commits into from
Jan 12, 2019

Conversation

cfromknecht
Copy link
Contributor

@cfromknecht cfromknecht commented Jul 20, 2018

This PR proposes a different gcs filter querying mechanism, intended for having better performance as the number of query entries surpasses the number of elements in the filter.

As the number of elements in the query grows, allocating and sorting the elements begins to dominate the runtime. The solution then for large queries is inspired by a hash join, which makes no assumptions on the input ordering of either set. Since the number of filters is ultimately bounded by the block size, the filter entries are chosen as the hash index so that the setup latency is minimized.

Complexity

Number of filter entries: F
Number of query entries: Q
Assumption: Q > F

Setup

Regular Hash
Keying Theta (Q) 0
Cmp O(Q log Q) Theta(F)
Read 0 Theta(F)
Memory Theta(Q) Theta(F)

Online

Regular Hash
Keying 0 O(Q)
Cmp O(F+Q) O(Q)
Read O(F) 0
Memory O(1) O(1)

Benchmarks

Zip w/ 5K Filter Elements

BenchmarkGCSFilterZipMatchAny/q100-f5K-8                   10000            214745 ns/op           14496 B/op          3 allocs/op
BenchmarkGCSFilterZipMatchAny/q1K-f5K-8                     5000            365375 ns/op           21792 B/op          3 allocs/op
BenchmarkGCSFilterZipMatchAny/q10K-f5K-8                    1000           1997457 ns/op           95520 B/op          3 allocs/op
BenchmarkGCSFilterZipMatchAny/q100K-f5K-8                    100          20662820 ns/op          816416 B/op          3 allocs/op
BenchmarkGCSFilterZipMatchAny/q1M-f5K-8                        5         243683419 ns/op         8017184 B/op          3 allocs/op

Zip w/ 10K Filter Elements

BenchmarkGCSFilterZipMatchAny/q100-f10K-8                   3000            674189 ns/op           28192 B/op          3 allocs/op
BenchmarkGCSFilterZipMatchAny/q1K-f10K-8                    2000            716604 ns/op           35488 B/op          3 allocs/op
BenchmarkGCSFilterZipMatchAny/q10K-f10K-8                   1000           2414061 ns/op          109216 B/op          3 allocs/op
BenchmarkGCSFilterZipMatchAny/q100K-f10K-8                   100          23639724 ns/op          830112 B/op          3 allocs/op
BenchmarkGCSFilterZipMatchAny/q1M-f10K-8                       5         246618280 ns/op         8030880 B/op          3 allocs/op

Hash-Join w/ 5K Filter Elements

BenchmarkGCSFilterHashMatchAny/q100-f5K-8                   3000            424421 ns/op           72351 B/op         11 allocs/op      
BenchmarkGCSFilterHashMatchAny/q1K-f5K-8                    3000            450057 ns/op           72348 B/op         11 allocs/op      
BenchmarkGCSFilterHashMatchAny/q10K-f5K-8                   2000            936740 ns/op           72347 B/op         11 allocs/op      
BenchmarkGCSFilterHashMatchAny/q100K-f5K-8                   200           6184445 ns/op           72340 B/op         11 allocs/op      
BenchmarkGCSFilterHashMatchAny/q1M-f5K-8                      50          31261020 ns/op           72422 B/op         11 allocs/op

Hash-Join w/ 10K Filter Elements

BenchmarkGCSFilterHashMatchAny/q100-f10K-8                  2000            890682 ns/op          136545 B/op         12 allocs/op
BenchmarkGCSFilterHashMatchAny/q1K-f10K-8                   2000            976564 ns/op          136513 B/op         12 allocs/op
BenchmarkGCSFilterHashMatchAny/q10K-f10K-8                  1000           1480180 ns/op          136564 B/op         12 allocs/op
BenchmarkGCSFilterHashMatchAny/q100K-f10K-8                  200           6389050 ns/op          136570 B/op         12 allocs/op
BenchmarkGCSFilterHashMatchAny/q1M-f10K-8                    300           5701372 ns/op          136512 B/op         12 allocs/op

Hybrid w/ 5k Filter Elements

BenchmarkGCSFilterMatchAny/q100-f5K-8                      10000            211485 ns/op           14496 B/op          3 allocs/op      
BenchmarkGCSFilterMatchAny/q1K-f5K-8                        5000            359744 ns/op           21792 B/op          3 allocs/op      
BenchmarkGCSFilterMatchAny/q10K-f5K-8                       2000            966623 ns/op           72346 B/op         11 allocs/op      
BenchmarkGCSFilterMatchAny/q100K-f5K-8                       200           6057262 ns/op           72340 B/op         11 allocs/op      
BenchmarkGCSFilterMatchAny/q1M-f5K-8                          50          31490692 ns/op           72319 B/op         11 allocs/op

Hybrid w/ 10k Filter Elements

BenchmarkGCSFilterMatchAny/q100-f10K-8                      3000            561779 ns/op           28192 B/op          3 allocs/op
BenchmarkGCSFilterMatchAny/q1K-f10K-8                       2000            725211 ns/op           35488 B/op          3 allocs/op
BenchmarkGCSFilterMatchAny/q10K-f10K-8                      1000           1431762 ns/op          136531 B/op         12 allocs/op
BenchmarkGCSFilterMatchAny/q100K-f10K-8                      200           6382231 ns/op          136457 B/op         12 allocs/op
BenchmarkGCSFilterMatchAny/q1M-f10K-8                        300           5611058 ns/op          136553 B/op         12 allocs/op

Ratio Zip/Hash

Latency Memory
q10K-f5K 2.13x 1.32x
q10K-f10K 1.63x 0.8x
q1M-f5K 7.80x 110.7x
q1M-f10K 43.3x 58.8x

@cfromknecht cfromknecht force-pushed the gcs-wumbo-match-any branch 2 times, most recently from e8ae6e6 to 12890a9 Compare July 20, 2018 07:39
@cfromknecht cfromknecht changed the title [gcs] MatchAnyWumbo: faster filter matches for large queries [gcs] HashMatchAny: faster filter matches for large queries Jul 20, 2018
@cfromknecht cfromknecht force-pushed the gcs-wumbo-match-any branch 4 times, most recently from 4babee0 to 938f41c Compare July 24, 2018 02:46
Copy link
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! This'll significantly speed up larger wallets that are using the neutrino protocol. I left one comment regarding the way it estimates which algorithm to us. As it, it compares the size of the filter, rather than the number of elements in the filter. Not sure if that was intended or not.

// TODO(conner): add real heuristics to query optimization
switch {

case len(data) >= int(f.N()/2):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So N here is actually the number of bytes, and not necessarily the number of elements as it's about 3 bit per element or so as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

turns out N is the number of elements, so i've left the heuristics in tact. did realize that the bench mark was using 2000 instead of 5000 so i went back and updated the body w/ metrics for 5k filters

Copy link
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🎨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants