From 9e5f4b9a998d263e3ce9c56664a7816001ac8000 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 24 Apr 2019 17:47:09 -0700 Subject: [PATCH] gcs/gcs: use sort.Slice instead of sort.Sort, remove uint64Slice This commit removes the uint64Slice type and performs sorting during filter construction and ZipMatchAny using sort.Slice. The benchmarks indicated that this speeds up BuildGCSFilter and ZipMatchAny by 10-12%, likely to the overhead of needing to resolve the sort.Interface methods. The benchmarks indicate that this improvement is not present for the smallest query size in our benchmarks, i.e. 100 elements, but the reduction is only about 3%. This would indicate the at these small values, the use of reflection is actually slightly slower than interface method resolution in total. --- gcs/gcs.go | 8 ++++---- gcs/uint64slice.go | 26 -------------------------- 2 files changed, 4 insertions(+), 30 deletions(-) delete mode 100644 gcs/uint64slice.go diff --git a/gcs/gcs.go b/gcs/gcs.go index ffdd012..cfe215c 100644 --- a/gcs/gcs.go +++ b/gcs/gcs.go @@ -119,7 +119,7 @@ func BuildGCSFilter(P uint8, M uint64, key [KeySize]byte, data [][]byte) (*Filte } // Build the filter. - values := make(uint64Slice, 0, len(data)) + values := make([]uint64, 0, len(data)) b := bstream.NewBStreamWriter(0) // Insert the hash (fast-ranged over a space of N*P) of each data @@ -138,7 +138,7 @@ func BuildGCSFilter(P uint8, M uint64, key [KeySize]byte, data [][]byte) (*Filte v = fastReduction(v, nphi, nplo) values = append(values, v) } - sort.Sort(values) + sort.Slice(values, func(i, j int) bool { return values[i] < values[j] }) // Write the sorted list of values into the filter bitstream, // compressing it using Golomb coding. @@ -374,7 +374,7 @@ func (f *Filter) ZipMatchAny(key [KeySize]byte, data [][]byte) (bool, error) { b := bstream.NewBStreamReader(filterData) // Create an uncompressed filter of the search values. - values := make(uint64Slice, 0, len(data)) + values := make([]uint64, 0, len(data)) // First, we cache the high and low bits of modulusNP for the // multiplication of 2 64-bit integers into a 128-bit integer. @@ -389,7 +389,7 @@ func (f *Filter) ZipMatchAny(key [KeySize]byte, data [][]byte) (bool, error) { v = fastReduction(v, nphi, nplo) values = append(values, v) } - sort.Sort(values) + sort.Slice(values, func(i, j int) bool { return values[i] < values[j] }) querySize := len(values) diff --git a/gcs/uint64slice.go b/gcs/uint64slice.go deleted file mode 100644 index 34fd2f0..0000000 --- a/gcs/uint64slice.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2016-2017 The btcsuite developers -// Copyright (c) 2016-2017 The Lightning Network Developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package gcs - -// uint64slice is a package-local utility class that allows us to use Go's sort -// package to sort a []uint64 by implementing sort.Interface. -type uint64Slice []uint64 - -// Len returns the length of the slice. -func (p uint64Slice) Len() int { - return len(p) -} - -// Less returns true when the ith element is smaller than the jth element of -// the slice, and returns false otherwise. -func (p uint64Slice) Less(i, j int) bool { - return p[i] < p[j] -} - -// Swap swaps two slice elements. -func (p uint64Slice) Swap(i, j int) { - p[i], p[j] = p[j], p[i] -}