package
1.8.0
Repository: https://github.com/elicdavis/vector.git
Documentation: pkg.go.dev

# README

Experiments

Different performance experiments to help inform this libraries design.

Golang: go1.21.0 windows/amd64

CPU: 13th Gen Intel(R) Core(TM) i7-13800H

Sum

Given an array of vectors and a vector A, return a new array that is the result of adding A to each element of the original array.

Results

For small array sizes, the immutable vector outperforms the mutable vector. But as the vector size grows, the opposite happens. Mutable vectors begin to out perform. Running this code on non x86 machine brings different, more predictable results however.

Take Away

The benchmarking results is probably just noise at the moment. This is further proved out in the Add benchmark.

Raw Data

goos: windows
goarch: amd64
pkg: github.com/EliCDavis/vector/experiments
cpu: 13th Gen Intel(R) Core(TM) i7-13800H
BenchmarkSumVector/Len-100-20   	         9706915	       116.1 ns/op	       0 B/op	       0 allocs/op
BenchmarkSumVector/Len-1000-20  	         1000000	      1133 ns/op	       0 B/op	       0 allocs/op
BenchmarkSumVector/Len-10000-20 	           89824	     13145 ns/op	       0 B/op	       0 allocs/op
BenchmarkSumVector/Len-100000-20         	   10000	    148563 ns/op	       0 B/op	       0 allocs/op
BenchmarkSumVector/Len-1000000-20        	     511	   2662477 ns/op	       0 B/op	       0 allocs/op
BenchmarkSumVector/Len-10000000-20       	      38	  26449755 ns/op	       0 B/op	       0 allocs/op
BenchmarkSumMutableVector/Len-100-20     	 9983551	       134.0 ns/op	       0 B/op	       0 allocs/op
BenchmarkSumMutableVector/Len-1000-20    	 1000000	      1113 ns/op	       0 B/op	       0 allocs/op
BenchmarkSumMutableVector/Len-10000-20   	   98847	     10837 ns/op	       0 B/op	       0 allocs/op
BenchmarkSumMutableVector/Len-100000-20  	    9955	    136423 ns/op	       0 B/op	       0 allocs/op
BenchmarkSumMutableVector/Len-1000000-20 	     666	   2055645 ns/op	       0 B/op	       0 allocs/op
BenchmarkSumMutableVector/Len-10000000-20         42	  27580652 ns/op	       0 B/op	       0 allocs/op

Formatted in CSV

vector type,    arr len,   times ran,     ns/op,    B/op, allocs/op
Vector,         100,         9706915,     116.1,    0,    0
Vector,         1000,        1000000,      1133,    0,    0
Vector,         10000,         89824,     13145,    0,    0
Vector,         100000,        10000,    148563,    0,    0
Vector,         1000000,         511,   2662477,    0,    0
Vector,         10000000,         38,  26449755,    0,    0
Mutable Vector, 100,         9983551,     134.0,    0,    0
Mutable Vector, 1000,        1000000,      1113,    0,    0
Mutable Vector, 10000,         98847,     10837,    0,    0
Mutable Vector, 100000,         9955,    136423,    0,    0
Mutable Vector, 1000000,         666,   2055645,    0,    0
Mutable Vector, 10000000,         42,  27580652,    0,    0

Add

Add one vector to another, saving the results away

Results

Both methods in which the structs, immutable or mutable, who take a struct as an argument and returns a new struct as the result, outperform everything else. Anytime a pointer is involved, performance starts to degrade. Side effects required for modifying the value of a mutable vector seems to degrade performance.

Take Away

Avoid using pointers. Having a method return a value isn't bad.

Raw Data

goos: windows
goarch: amd64
pkg: github.com/EliCDavis/vector/experiments
cpu: 13th Gen Intel(R) Core(TM) i7-13800H
BenchmarkAddVector-20                                           	1000000000	         0.8899 ns/op	       0 B/op	       0 allocs/op
BenchmarkAddMutableVector-20                                    	1000000000	         0.8704 ns/op	       0 B/op	       0 allocs/op
BenchmarkAddMutableVectorInPlace-20                             	372655183	         3.291 ns/op	       0 B/op	       0 allocs/op
BenchmarkAddMutableVectorInPlaceUsingPointer-20                 	396180162	         3.012 ns/op	       0 B/op	       0 allocs/op
BenchmarkAddMutableVectorInPlaceWithReturn-20                   	350640970	         3.527 ns/op	       0 B/op	       0 allocs/op
BenchmarkAddMutableVectorInPlaceWithReturnUsingPointer-20       	396528655	         3.077 ns/op	       0 B/op	       0 allocs/op
BenchmarkAddMutableVectorInPlaceTakingPointerUsingPointer-20    	393230407	         3.249 ns/op	       0 B/op	       0 allocs/op

Formatted in CSV

benchmark,                                                  times ran,   ns/op,   B/op,  allocs/op
Add Vector,                                                 1000000000,  0.8899,  0,     0
Add Mutable Vector,                                         1000000000,  0.8704,  0,     0
Add Mutable Vector In Place,                                372655183,   3.291,   0,     0
Add Mutable Vector In Place Using Pointer,                  396180162,   3.012,   0,     0
Add Mutable Vector In Place With Return,                    350640970,   3.527,   0,     0
Add Mutable Vector In Place With Return Using Pointer,      396528655,   3.077,   0,     0
Add Mutable Vector In Place Taking Pointer Using Pointer,   393230407,   3.249,   0,     0

Accessor

Testing whether or not using a function to access a specific component in a vector is detrimental to perforamnce.

Results

Both using a function to access a variable of a struct, and just referencing the variable directly perform almost the same. Given it's sub nanosecond, any difference is hard to tease out due to it probably being noise.

Takeaway

Using a function to access a component in a vector is Okay.

Raw Data

goos: windows
goarch: amd64
pkg: github.com/EliCDavis/vector/experiments
cpu: 13th Gen Intel(R) Core(TM) i7-13800H
BenchmarkAccessVector-20           1000000000         0.5130 ns/op       0 B/op       0 allocs/op
BenchmarkAccessMutableVector-20    1000000000         0.5163 ns/op       0 B/op       0 allocs/op

Formatted in CSV

benchmark,              times ran,   ns/op,     B/op,  allocs/op
Access Vector           1000000000,  0.5130,    0,     0,
Access MutableVector    1000000000,  0.5163,    0,     0,