public void SliceDisposeBenchmark() { // 6.3 MOPS var count = 1_000_000; var rounds = 10; var arrSize = 1000; var arr = Enumerable.Range(0, arrSize).ToArray(); var mem = ArrayMemory <int> .Create(arr, 0, arr.Length, externallyOwned : true, pin : true); var vs = VectorStorage.Create(mem, 0, mem.Length); Assert.AreEqual(arr.Length, vs.Length); for (int r = 0; r < rounds; r++) { using (Benchmark.Run("Slice/Dispose", count)) { for (int i = 0; i < count; i++) { var vs1 = vs.Slice(0, vs.Vec.Length, 1, externallyOwned: true); vs1.Dispose(); } } } Benchmark.Dump(); vs.Dispose(); Assert.IsTrue(vs.IsDisposed); }
public void CouldCreateVsAndReadElements() { var count = 1000; var arr = Enumerable.Range(0, count).ToArray(); var r = ArrayMemory <int> .Create(arr, 0, arr.Length, externallyOwned : true, pin : true); var vs = VectorStorage.Create(r, 0, r.Length); Assert.AreEqual(arr.Length, vs.Length); long sum = 0L; for (int i = 0; i < arr.Length; i++) { var vi = vs.DangerousGet <int>(i); if (vi != i) { Assert.Fail("vi != i"); } sum += vs.DangerousGet <int>(i); } Console.WriteLine(sum); vs.Dispose(); Assert.IsTrue(vs.IsDisposed); }
public unsafe int Read(ref DirectBuffer source, out VectorStorage <T> value) { var arraySize = source.Read <int>(0); if (arraySize > 0) { ThrowHelper.ThrowNotImplementedException("Non-shuffled arrays are not implemented yet"); // TODO } arraySize = -arraySize; // var position = 4; var payloadSize = arraySize * Unsafe.SizeOf <T>(); if (4 + payloadSize > source.Length || arraySize < 0) { value = default; return(-1); } if (arraySize > 0) { var byteLen = Unsafe.SizeOf <T>() * arraySize; var rm = BufferPool <T> .MemoryPool.RentMemory(arraySize) as ArrayMemory <T>; Debug.Assert(rm != null); // ReSharper disable once PossibleNullReferenceException fixed(byte *dPtr = &Unsafe.As <T, byte>(ref rm.Vec.DangerousGetRef(0))) { var srcDb = source.Slice(4); var destDb = new DirectBuffer(byteLen, dPtr); // srcDb.CopyTo(destDb); BinarySerializer.Unshuffle(in srcDb, in destDb, (byte)Unsafe.SizeOf <T>()); } if (TypeHelper <T> .IsIDelta) { var first = (IDelta <T>)rm.Array[0]; for (int i = 1; i < arraySize; i++) { rm.Array[i] = first.AddDelta(rm.Array[i]); } } var vs = VectorStorage.Create <T>(rm, 0, arraySize); value = new VectorStorage <T>(vs); } else { value = new VectorStorage <T>(VectorStorage.Empty); } return(4 + payloadSize); }
private static BaseContainer <int> CreateIntBaseContainer(int capacity, int length) { var bc = new BaseContainer <int>(); var rm = ArrayMemory <int> .Create(Enumerable.Range(0, capacity).ToArray(), externallyOwned : true); var vs = VectorStorage.Create(rm, 0, rm.Length, 1); var block = DataBlock.Create(rowIndex: vs, rowLength: length); bc.DataBlock = block; return(bc); }
public void VectorStorageReadBench() { var count = 1_000_000; var rounds = 10; var mult = 500; var arr = Enumerable.Range(0, count).ToArray(); var mem = ArrayMemory <int> .Create(arr, 0, arr.Length, externallyOwned : true, pin : true); var stride = 2; var vs = VectorStorage.Create(mem, (stride - 1), mem.Length - (stride - 1), stride); Assert.AreEqual(arr.Length / stride, vs.Length); int sum = 0; for (int r = 0; r < rounds; r++) { using (Benchmark.Run("VS Read", vs.Length * mult)) { var vector = vs.GetVector <int>(); for (int _ = 0; _ < mult; _++) { for (int i = 0; i < vs.Length; i++) { var vi = vector[i]; if (vi != i * stride + (stride - 1)) { Assert.Fail("vi != i * 2"); } unchecked { sum += vi; } } } } } Benchmark.Dump(); Console.WriteLine(sum); }
public void CouldTryFindBlockAtSingleChunkBench() { var count = 50_000_000; var rounds = 20; // for this test capacity is irrelevant - interpolation search hits exact position on first try var capacity = count / 100; var bc = new BaseContainer <int>(); var rm = ArrayMemory <int> .Create(Enumerable.Range(0, capacity).ToArray(), externallyOwned : true); var vs = VectorStorage.Create(rm, 0, rm.Length, 1); var block = DataBlock.Create(rowIndex: vs, rowLength: vs.Length); bc.DataBlock = block; for (int r = 0; r < rounds; r++) { using (Benchmark.Run("TryFindChunkAt", count)) { var m = count / capacity; for (int _ = 0; _ < m; _++) { for (int i = 1; i < capacity; i++) { var searchIndexRef = i; var found = bc.TryFindBlockAt(ref searchIndexRef, Lookup.LE, out var c, out var ci); if (!found || !ReferenceEquals(block, c) || i != ci || i != searchIndexRef ) { Assert.Fail(); } } } } } Benchmark.Dump(); bc.Dispose(); }
public Series(TKey[] keys, TValue[] values) { if (keys.Length != values.Length) { throw new ArgumentException("Different keys and values length"); } var ks = KeySorting.Strong; if (keys.Length > 1) { var cmp = KeyComparer <TKey> .Default; for (int i = 1; i < keys.Length; i++) { var c = cmp.Compare(keys[i], keys[i - 1]); if (c == 0) { ks = KeySorting.Weak; } else if (c < 0) { ks = KeySorting.NotSorted; break; } } } _flags = new Flags((byte)((byte)Mutability.Immutable | (byte)ks)); var keyMemory = ArrayMemory <TKey> .Create(keys, externallyOwned : true); var keyVs = VectorStorage.Create(keyMemory, 0, keyMemory.Length, 1); var valMemory = ArrayMemory <TValue> .Create(values, externallyOwned : true); var valVs = VectorStorage.Create(valMemory, 0, valMemory.Length, 1); var block = DataBlock.Create(rowIndex: keyVs, values: valVs, rowLength: keys.Length); DataBlock = block; }
public void CouldTryGetBlockAtSingleChunk() { var capacity = 100; var bc = new BaseContainer <int>(); var rm = ArrayMemory <int> .Create(Enumerable.Range(0, capacity).ToArray(), externallyOwned : true); var vs = VectorStorage.Create(rm, 0, rm.Length, 1); var block = DataBlock.Create(rowIndex: vs, rowLength: vs.Length / 2); bc.DataBlock = block; var searchIndex = 40; var found = bc.TryGetBlockAt(searchIndex, out var c, out var ci); Assert.IsTrue(found); Assert.AreSame(block, c); Assert.AreEqual(searchIndex, ci); bc.Dispose(); }
public void CouldTryFindBlockAtSingleChunk() { var capacity = 100; var bc = new BaseContainer <long>(); var rm = ArrayMemory <long> .Create(Enumerable.Range(0, capacity).Select(x => (long)x).ToArray(), externallyOwned : true); var vs = VectorStorage.Create(rm, 0, rm.Length, 1); var block = DataBlock.Create(rowIndex: vs, rowLength: vs.Length / 2); bc.DataBlock = block; var searchIndex = 40L; var searchIndexRef = searchIndex; var found = bc.TryFindBlockAt(ref searchIndexRef, Lookup.LT, out var c, out var ci); Assert.IsTrue(found); Assert.AreSame(block, c); Assert.AreEqual(searchIndex - 1, ci); Assert.AreEqual(searchIndex - 1, searchIndexRef); bc.Dispose(); }
public void CouldSerializeVectorStorage() { var rng = new Random(42); var count = 100_000; var arr = new SmallDecimal[count]; arr[0] = new SmallDecimal(1000 * 1.0, 4); for (int i = 1; i < count; i++) { arr[i] = arr[i - 1] + new SmallDecimal((double)arr[i - 1] * (0.02 + -0.04 * rng.NextDouble()), 4); } // arr = Enumerable.Range(0, count).Select(x => new SmallDecimal(1000 + (double)x + (double)Math.Round(0.1 * rng.NextDouble(), 5), precision:3)).ToArray(); var r = ArrayMemory <SmallDecimal> .Create(arr, 0, arr.Length, externallyOwned : true, pin : true); var vs = VectorStorage.Create(r, 0, r.Length); var vsT = new VectorStorage <SmallDecimal>(vs); var payload = count * Unsafe.SizeOf <double>() + 4; foreach (SerializationFormat format in ((SerializationFormat[])Enum.GetValues(typeof(SerializationFormat))).OrderBy(e => e.ToString())) { var len = BinarySerializer.SizeOf(in vsT, out var rm, format); var destination = BufferPool.Retain(len); var destinationDb = new DirectBuffer(destination); var len1 = BinarySerializer.Write(in vsT, ref destinationDb, in rm, format); Assert.AreEqual(destination.Length, destinationDb.Length); Assert.AreEqual(len, len1); var flags = destinationDb.Read <VersionAndFlags>(0); Assert.AreEqual(format, flags.SerializationFormat); var header = destinationDb.Read <DataTypeHeader>(0); Assert.AreEqual(TypeEnum.VectorStorage, header.TypeEnum); Assert.AreEqual(TypeEnum.SmallDecimal, header.ElementTypeEnum); Assert.AreEqual(Unsafe.SizeOf <SmallDecimal>(), header.TypeSize); var len2 = BinarySerializer.Read(ref destinationDb, out VectorStorage <SmallDecimal> value); Assert.AreEqual(destination.Length, destinationDb.Length); Assert.AreEqual(len, len2); Assert.AreEqual(vs.Length, value.Storage.Length); for (int i = 0; i < count; i++) { SmallDecimal left; SmallDecimal right; if ((left = vs.Vec.DangerousGetRef <SmallDecimal>(i)) != (right = value.Storage.DangerousGetRef <SmallDecimal>(i))) { Console.WriteLine("Not equals"); } } Assert.IsTrue(vs.Vec.Slice(0, vs.Length).AsSpan <SmallDecimal>().SequenceEqual(value.Storage.Vec.Slice(0, value.Storage.Length).AsSpan <SmallDecimal>())); Console.WriteLine($"{format} len: {len:N0} x{Math.Round((double)payload/len, 2)}"); destination.Dispose(); value.Storage.Dispose(); } vs.Dispose(); Assert.IsTrue(vs.IsDisposed); }