From 0572790504b1939fe5cab2976dd8531aca315c8b Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Fri, 16 Apr 2021 15:24:29 -0400 Subject: [PATCH 1/3] This should reduce bound checks in a function. --- setutil_generic.go | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/setutil_generic.go b/setutil_generic.go index 9edcc902..3668f800 100644 --- a/setutil_generic.go +++ b/setutil_generic.go @@ -2,10 +2,13 @@ package roaring + func union2by2(set1 []uint16, set2 []uint16, buffer []uint16) int { - pos := 0 - k1 := 0 - k2 := 0 + pos := uint(0) + k1 := uint(0) + k2 := uint(0) + len1 := uint(len(set1)) + len2 := uint(len(set2)) if 0 == len(set2) { buffer = buffer[:len(set1)] copy(buffer, set1[:]) @@ -20,29 +23,34 @@ func union2by2(set1 []uint16, set2 []uint16, buffer []uint16) int { s2 := set2[k2] buffer = buffer[:cap(buffer)] for { + if pos >= uint(len(buffer)) { + panic("You provided a buffer with insufficient capacity") + } if s1 < s2 { buffer[pos] = s1 pos++ k1++ - if k1 >= len(set1) { + if k1 >= len1 { copy(buffer[pos:], set2[k2:]) - pos += len(set2) - k2 - break + pos += len2 - k2 + return int(pos) + } + if k1 < len1 { + s1 = set1[k1] } - s1 = set1[k1] } else if s1 == s2 { buffer[pos] = s1 pos++ k1++ k2++ - if k1 >= len(set1) { + if k1 >= len1 { copy(buffer[pos:], set2[k2:]) - pos += len(set2) - k2 + pos += len2 - k2 break } - if k2 >= len(set2) { + if k2 >= len2 { copy(buffer[pos:], set1[k1:]) - pos += len(set1) - k1 + pos += len1 - k1 break } s1 = set1[k1] @@ -51,13 +59,13 @@ func union2by2(set1 []uint16, set2 []uint16, buffer []uint16) int { buffer[pos] = s2 pos++ k2++ - if k2 >= len(set2) { + if k2 >= len2 { copy(buffer[pos:], set1[k1:]) - pos += len(set1) - k1 + pos += len1 - k1 break } s2 = set2[k2] } } - return pos + return int(pos) } From 9f95696ce93b44ce22c97ad064481cab5c2e5771 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Fri, 16 Apr 2021 15:31:32 -0400 Subject: [PATCH 2/3] Tuning. --- setutil_generic.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/setutil_generic.go b/setutil_generic.go index 3668f800..aa5bc7d0 100644 --- a/setutil_generic.go +++ b/setutil_generic.go @@ -21,8 +21,8 @@ func union2by2(set1 []uint16, set2 []uint16, buffer []uint16) int { } s1 := set1[k1] s2 := set2[k2] - buffer = buffer[:cap(buffer)] - for { + buffer = buffer[:len1 + len2] + for pos < uint(len(buffer)) { if pos >= uint(len(buffer)) { panic("You provided a buffer with insufficient capacity") } @@ -35,9 +35,7 @@ func union2by2(set1 []uint16, set2 []uint16, buffer []uint16) int { pos += len2 - k2 return int(pos) } - if k1 < len1 { - s1 = set1[k1] - } + s1 = set1[k1] } else if s1 == s2 { buffer[pos] = s1 pos++ From 2e7b454e4198e29b23f64589d15a05f911474096 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Fri, 16 Apr 2021 15:40:34 -0400 Subject: [PATCH 3/3] Removing dead code. --- setutil_generic.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/setutil_generic.go b/setutil_generic.go index aa5bc7d0..9fcdd0b6 100644 --- a/setutil_generic.go +++ b/setutil_generic.go @@ -23,9 +23,6 @@ func union2by2(set1 []uint16, set2 []uint16, buffer []uint16) int { s2 := set2[k2] buffer = buffer[:len1 + len2] for pos < uint(len(buffer)) { - if pos >= uint(len(buffer)) { - panic("You provided a buffer with insufficient capacity") - } if s1 < s2 { buffer[pos] = s1 pos++