github.com/moontrade/nogc@v0.1.7/tinygc_test.go (about)

     1  package nogc
     2  
     3  import (
     4  	"testing"
     5  )
     6  
     7  func TestGC(t *testing.T) {
     8  	// Create a simple roots marking system
     9  	// This will provided by the runtime / compiler in TinyGo.
    10  	roots := make(map[uintptr]struct{})
    11  	var gc *gc
    12  	markGlobals := func() {
    13  		for k := range roots {
    14  			gc.markRoot(k)
    15  		}
    16  	}
    17  	// Create GC
    18  	gc = newGC(16, markGlobals, nil)
    19  
    20  	// Allocate root
    21  	root := func(size uintptr) uintptr {
    22  		p := gc.New(size)
    23  		roots[p] = struct{}{}
    24  		return p
    25  	}
    26  	// Allocate and leak
    27  	leak := func(size uintptr) uintptr {
    28  		return gc.New(size)
    29  	}
    30  
    31  	// Do some allocations
    32  	root(64)
    33  	root(72)
    34  	gc.Free(leak(128))
    35  	leak(512)
    36  
    37  	// Print before
    38  	gc.Print()
    39  	println()
    40  
    41  	// Run full GC collect
    42  	gc.Collect()
    43  
    44  	// Print after
    45  	gc.Print()
    46  	println()
    47  }
    48  
    49  //func BenchmarkHashSet(b *testing.B) {
    50  //	m := make(map[uintptr]struct{}, 16)
    51  //	m[1000] = struct{}{}
    52  //	a := NewTLSFArena(1, NewSliceArena(), GrowMin)
    53  //	set := NewPointerSet(a.AsAllocator(), 16)
    54  //	set.Put(1000)
    55  //	s := &set
    56  //
    57  //	b.Run("map get exists", func(b *testing.B) {
    58  //		for i := 0; i < b.N; i++ {
    59  //			_, _ = m[1000]
    60  //		}
    61  //	})
    62  //	b.Run("moon get exists", func(b *testing.B) {
    63  //		for i := 0; i < b.N; i++ {
    64  //			_ = s.Has(1000)
    65  //		}
    66  //	})
    67  //
    68  //	b.Run("map get not exists", func(b *testing.B) {
    69  //		for i := 0; i < b.N; i++ {
    70  //			_, _ = m[1001]
    71  //		}
    72  //	})
    73  //	b.Run("moon get not exists", func(b *testing.B) {
    74  //		for i := 0; i < b.N; i++ {
    75  //			_ = s.Has(1001)
    76  //		}
    77  //	})
    78  //
    79  //	b.Run("map Add", func(b *testing.B) {
    80  //		for i := 0; i < b.N; i++ {
    81  //			m[1001] = struct{}{}
    82  //		}
    83  //	})
    84  //	b.Run("moon Add", func(b *testing.B) {
    85  //		for i := 0; i < b.N; i++ {
    86  //			_, _ = s.Put(1001)
    87  //		}
    88  //	})
    89  //
    90  //	b.Run("map Delete", func(b *testing.B) {
    91  //		for i := 0; i < b.N; i++ {
    92  //			delete(m, 1001)
    93  //		}
    94  //	})
    95  //	b.Run("moon Delete", func(b *testing.B) {
    96  //		for i := 0; i < b.N; i++ {
    97  //			_, _ = s.Delete(1001)
    98  //		}
    99  //	})
   100  //}
   101  //
   102  //func BenchmarkHashSetHashAlgos(b *testing.B) {
   103  //	a := NewTLSFArena(1, NewSliceArena(), GrowMin)
   104  //	set := NewPointerSet(a.AsAllocator(), 16)
   105  //	set.Put(1000)
   106  //	s := &set
   107  //
   108  //	get := func(name string, algo func(uint32) uint32) {
   109  //		b.Run(name+" get exists", func(b *testing.B) {
   110  //			pointerSetHash = algo
   111  //			for i := 0; i < b.N; i++ {
   112  //				_ = s.Has(1000)
   113  //			}
   114  //		})
   115  //	}
   116  //	getNot := func(name string, algo func(uint32) uint32) {
   117  //		b.Run(name+"get not exists", func(b *testing.B) {
   118  //			pointerSetHash = algo
   119  //			for i := 0; i < b.N; i++ {
   120  //				_ = s.Has(1001)
   121  //			}
   122  //		})
   123  //	}
   124  //
   125  //	doSet := func(name string, algo func(uint32) uint32) {
   126  //		b.Run(name+" Add", func(b *testing.B) {
   127  //			pointerSetHash = algo
   128  //			for i := 0; i < b.N; i++ {
   129  //				_, _ = s.Put(1001)
   130  //			}
   131  //		})
   132  //	}
   133  //	del := func(name string, algo func(uint32) uint32) {
   134  //		b.Run(name+" Delete", func(b *testing.B) {
   135  //			pointerSetHash = algo
   136  //			for i := 0; i < b.N; i++ {
   137  //				_, _ = s.Delete(1001)
   138  //			}
   139  //		})
   140  //	}
   141  //
   142  //	get("fnv", fnv32)
   143  //	get("adler32", adler32)
   144  //	get("wyhash", wyhash32)
   145  //	get("metro", metro32)
   146  //
   147  //	getNot("fnv", fnv32)
   148  //	getNot("adler32", adler32)
   149  //	getNot("wyhash", wyhash32)
   150  //	getNot("metro", metro32)
   151  //
   152  //	doSet("fnv", fnv32)
   153  //	doSet("adler32", adler32)
   154  //	doSet("wyhash", wyhash32)
   155  //	doSet("metro", metro32)
   156  //
   157  //	del("fnv", fnv32)
   158  //	del("adler32", adler32)
   159  //	del("wyhash", wyhash32)
   160  //	del("metro", metro32)
   161  //}
   162  //
   163  //func Test_ThrashPointerSet(t *testing.T) {
   164  //	allocator := NewTLSF(25)
   165  //
   166  //	var (
   167  //		iterations                 = 1000
   168  //		heapBase           uintptr = 67056
   169  //		allocsPerIteration         = 100
   170  //		minAllocs                  = 32
   171  //		maxAllocs                  = 512
   172  //	)
   173  //
   174  //	run := func(name string, fn func(uint32) uint32) {
   175  //		_set := NewPointerSet(allocator.AsAllocator(), uintptr(maxAllocs*128))
   176  //		set := &_set
   177  //		defer set.Close()
   178  //		pointerSetHash = fn
   179  //		println(name+" collisions", thrashPointerSet(set, heapBase, true,
   180  //			iterations, allocsPerIteration, minAllocs, maxAllocs,
   181  //			//randomSize(0.95, 16, 48),
   182  //			randomSize(1, 24, 384),
   183  //			//randomSize(0.55, 64, 512),
   184  //			//randomSize(0.70, 128, 512),
   185  //			//randomSize(0.15, 128, 512),
   186  //			//randomSize(0.30, 128, 1024),
   187  //		))
   188  //	}
   189  //
   190  //	run("fnv", fnv32)
   191  //	run("wy", wyhash32)
   192  //	run("metro", metro32)
   193  //	run("adler", adler32)
   194  //}
   195  //
   196  //func thrashPointerSet(
   197  //	set *PointerSet,
   198  //	heapBase uintptr,
   199  //	shuffle bool,
   200  //	iterations, allocsPerIteration, minAllocs, maxAllocs int,
   201  //	sizeClasses ...*sizeClass,
   202  //) int64 {
   203  //	type allocation struct {
   204  //		ptr  Pointer
   205  //		size uintptr
   206  //	}
   207  //
   208  //	sz := make([]int, 0, allocsPerIteration)
   209  //	for _, sc := range sizeClasses {
   210  //		for i := 0; i < int(float64(allocsPerIteration)*sc.pct); i++ {
   211  //			sz = append(sz, sc.next())
   212  //		}
   213  //	}
   214  //
   215  //	allocs := make([]allocation, 0, maxAllocs)
   216  //	var (
   217  //		collisions    int64   = 0
   218  //		allocSize     uintptr = 0
   219  //		totalAllocs           = 0
   220  //		totalFrees            = 0
   221  //		maxAllocCount         = 0
   222  //		maxAllocSize  uintptr = 0
   223  //	)
   224  //
   225  //	rand.Seed(time.Now().UnixNano())
   226  //
   227  //	start := time.Now()
   228  //	for i := 0; i < iterations; i++ {
   229  //		rand.Shuffle(len(sz), func(i, j int) { sz[i], sz[j] = sz[j], sz[i] })
   230  //
   231  //		nextPtr := Pointer(heapBase)
   232  //		for _, size := range sz {
   233  //			allocs = append(allocs, allocation{
   234  //				ptr:  nextPtr,
   235  //				size: uintptr(size),
   236  //			})
   237  //			allocSize += uintptr(size)
   238  //			if !set.Has(nextPtr) {
   239  //				if set.isCollision(nextPtr) {
   240  //					collisions++
   241  //				}
   242  //				set.Put(nextPtr)
   243  //			}
   244  //			nextPtr += Pointer(size)
   245  //		}
   246  //		totalAllocs += len(sz)
   247  //
   248  //		if maxAllocCount < len(allocs) {
   249  //			maxAllocCount = len(allocs)
   250  //		}
   251  //		if allocSize > maxAllocSize {
   252  //			maxAllocSize = allocSize
   253  //		}
   254  //
   255  //		if len(allocs) < minAllocs || len(allocs) < maxAllocs {
   256  //			continue
   257  //		}
   258  //
   259  //		rand.Shuffle(len(allocs), func(i, j int) { allocs[i], allocs[j] = allocs[j], allocs[i] })
   260  //		max := randomRange(minAllocs, maxAllocs)
   261  //		//max := maxAllocs
   262  //		totalFrees += len(allocs) - max
   263  //		for x := max; x < len(allocs); x++ {
   264  //			alloc := allocs[x]
   265  //			set.Delete(alloc.ptr)
   266  //			allocSize -= alloc.size
   267  //		}
   268  //		allocs = allocs[:max]
   269  //	}
   270  //
   271  //	_ = start
   272  //
   273  //	return collisions
   274  //}