From 33ae8744f587a0577bf461d33bd6480a5b8503ed Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Sun, 17 Nov 2024 10:16:48 -0500 Subject: [PATCH] =?UTF-8?q?Fast=20skip=20ahead=20for=20blocks=20of=20equal?= =?UTF-8?q?=20values=20in=20i8=20and=20i16=20/=E2=81=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/singeli/src/count.singeli | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/singeli/src/count.singeli b/src/singeli/src/count.singeli index 9201a047..e06695c6 100644 --- a/src/singeli/src/count.singeli +++ b/src/singeli/src/count.singeli @@ -32,8 +32,18 @@ fn count{T if T<=i16}(tab:*u16, ov:*u16, xp:*void, n:u64, min_allowed:T) : T = { # Also record number of differences dc # (double-counts at index vec but it doesn't need to be exact) xv := *V~~x - jv := load{xv}; mv := jv; dc := -(jv != load{*V~~(x+1)}) - @for (xv, xp in *V~~(x-1) over _ from 1 to b) { + jv := load{xv}; mv := jv + ne := jv != load{*V~~(x+1)}; dc := -ne + # Quickly skip ahead if initial values are all equal + a:u64 = 1 + if (not homAny{ne} and b>=4) { + def eq_k{k} = homAll{tree_fold{&, @unroll(x in xv+a over k) x==jv}} + def skip_eq{k} = if (eq_k{k}) { a=2*k; skip_eq{2*k} } + def skip_eq{k==4} = while (a<=b-k and eq_k{k}) a+=k + skip_eq{1} + } + # Now start analysis + @for (xv, xp in *V~~(x-1) over _ from a to b) { jv = min{jv, xv}; mv = max{mv, xv} dc -= xp != xv }