From 1539d9d95bd5cfe3c532696f73195057fd1a5698 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Tue, 25 Jul 2017 09:50:49 +0200 Subject: [PATCH] optimized intsets to not allocate for the common cases --- lib/pure/collections/intsets.nim | 177 +++++++++++++++++++++---------- 1 file changed, 119 insertions(+), 58 deletions(-) diff --git a/lib/pure/collections/intsets.nim b/lib/pure/collections/intsets.nim index cf7aab18e..334e33f2e 100644 --- a/lib/pure/collections/intsets.nim +++ b/lib/pure/collections/intsets.nim @@ -31,16 +31,18 @@ const type PTrunk = ref Trunk - Trunk {.final.} = object + Trunk = object next: PTrunk # all nodes are connected with this pointer key: int # start address at bit 0 bits: array[0..IntsPerTrunk - 1, BitScalar] # a bit vector TrunkSeq = seq[PTrunk] IntSet* = object ## an efficient set of 'int' implemented as a sparse bit set + elems: int # only valid for small numbers counter, max: int head: PTrunk data: TrunkSeq + a: array[0..33, int] # profiling shows that 34 elements are enough {.deprecated: [TIntSet: IntSet, TTrunk: Trunk, TTrunkSeq: TrunkSeq].} @@ -95,99 +97,152 @@ proc intSetPut(t: var IntSet, key: int): PTrunk = proc contains*(s: IntSet, key: int): bool = ## returns true iff `key` is in `s`. - var t = intSetGet(s, `shr`(key, TrunkShift)) - if t != nil: - var u = key and TrunkMask - result = (t.bits[`shr`(u, IntShift)] and `shl`(1, u and IntMask)) != 0 + if s.elems <= s.a.len: + for i in 0..