1 module containers_ex; 2 3 version = benchmark; 4 5 import std.range : isInputRange; 6 private import std.experimental.allocator.mallocator : Mallocator; 7 8 /** Instantiator for $(D HashSet) in $(D containers-em). 9 */ 10 auto hashSet(Allocator = Mallocator, R)(R r) 11 if (isInputRange!R) 12 { 13 import std.range : ElementType, hasLength; 14 alias E = ElementType!R; // TODO Unqual? 15 16 import containers.hashset : HashSet; 17 static if (is(Allocator == Mallocator)) 18 { 19 static if (hasLength!R) 20 { 21 const bucketCount = r.length; // TODO use 22 auto set = HashSet!(E, Allocator)(); 23 } 24 else 25 { 26 auto set = HashSet!(E, Allocator)(); 27 } 28 } 29 else 30 { 31 static if (hasLength!R) 32 { 33 const bucketCount = r.length; // TODO use 34 auto set = HashSet!(E, Allocator)(Allocator()); 35 } 36 else 37 { 38 auto set = HashSet!(E, Allocator)(Allocator()); 39 } 40 } 41 42 foreach (const e; r) 43 { 44 set.insert(e); 45 } 46 47 return set; // make it const to indicate fixed 48 } 49 50 unittest 51 { 52 const x = [1, 2, 3, 2, 1]; 53 auto hx = x.hashSet; 54 assert(1 in hx); 55 assert(2 in hx); 56 assert(3 in hx); 57 static assert(is(typeof(3 in hx) == const(int)*)); 58 } 59 60 version(none) unittest 61 { 62 import std.range : iota; 63 import std.algorithm : count; 64 enum n = 1024* 1024; 65 66 alias T = int; 67 68 void testHashSetMallocator() 69 { 70 auto hx = iota!T(0, n).hashSet; 71 } 72 73 void testHashSetInSituRegion() 74 { 75 import std.experimental.allocator.building_blocks.region : Region, InSituRegion; 76 import std.experimental.allocator.mallocator : Mallocator; 77 import std.experimental.allocator.building_blocks.allocator_list : AllocatorList; 78 79 import std.algorithm : max; 80 // Create a scalable list of regions. Each gets at least 1MB at a time by using malloc. 81 alias LocalAllocator = InSituRegion!(n, T.alignof); 82 auto hx = iota!T(0, n).hashSet!LocalAllocator; // TODO Use LocalAllocator 83 } 84 85 void testAA() 86 { 87 bool[T] aa; 88 foreach (const e; iota!T(0, n)) { aa[e] = true; } 89 } 90 91 import std.datetime : benchmark, Duration; 92 auto r = benchmark!(testHashSetMallocator, 93 testHashSetInSituRegion, 94 testAA)(10); 95 import std.stdio : writeln; 96 97 import std.conv : to; 98 writeln("testHashSetMallocator: ", to!Duration(r[0])); 99 writeln("testHashSetInSituRegion: ", to!Duration(r[1])); 100 writeln("testAA: ", to!Duration(r[2])); 101 }