Last active
May 23, 2017 06:44
-
-
Save itn3000/b231af980f4db798dd6cd2cdc8bef506 to your computer and use it in GitHub Desktop.
implementation of ValueArraySegment
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| namespace bufferpooltest | |
| { | |
| using System; | |
| using System.Collections; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using Stopwatch = System.Diagnostics.Stopwatch; | |
| static class TestValueArray | |
| { | |
| const int LoopCount = 100000000; | |
| const int DebugOutInterval = LoopCount / 10; | |
| public static void TestValueArraySegment() | |
| { | |
| const int loopCount = LoopCount; | |
| var bytes = Enumerable.Range(0, 1024).Select(i => (byte)(i % 0xff)).ToArray(); | |
| long count = 0; | |
| var sw = new Stopwatch(); | |
| sw.Start(); | |
| for (int i = 0; i < loopCount; i++) | |
| { | |
| var seg = new ValueArraySegment<byte>(bytes, 10, 20); | |
| foreach (var b in seg) | |
| { | |
| count += b; | |
| } | |
| if (i % DebugOutInterval == DebugOutInterval - 1) | |
| { | |
| Console.WriteLine($"ValueArray:{i},{count}"); | |
| } | |
| } | |
| sw.Stop(); | |
| Console.WriteLine($"{count},{sw.Elapsed}"); | |
| count = 0; | |
| sw.Reset(); | |
| sw.Start(); | |
| for (int i = 0; i < loopCount; i++) | |
| { | |
| var seg2 = new ArraySegment<byte>(bytes, 10, 20); | |
| foreach (var b in seg2) | |
| { | |
| count += b; | |
| } | |
| if (i % DebugOutInterval == DebugOutInterval - 1) | |
| { | |
| Console.WriteLine($"Array:{i},{count}"); | |
| } | |
| } | |
| sw.Stop(); | |
| Console.WriteLine($"{count},{sw.Elapsed}"); | |
| } | |
| } | |
| struct ValueArraySegment<T> : IEnumerable<T> | |
| { | |
| int _offset; | |
| int _count; | |
| T[] _array; | |
| public T[] Array { get { return _array; } } | |
| public int Count { get { return _count; } } | |
| public int Offset { get { return _offset; } } | |
| public ValueArraySegment(T[] ar, int offset, int count) | |
| { | |
| _array = ar; | |
| _offset = offset; | |
| _count = count; | |
| } | |
| public T this[int index] | |
| { | |
| get | |
| { | |
| return _array[_offset + index]; | |
| } | |
| } | |
| public struct Enumerator : IEnumerator<T> | |
| { | |
| T[] m_Array; | |
| int CurrentIndex; | |
| int EndIndex; | |
| // int Offset; | |
| // bool IsEnd; | |
| public bool MoveNext() | |
| { | |
| if (CurrentIndex >= EndIndex - 1) | |
| { | |
| return false; | |
| } | |
| else | |
| { | |
| CurrentIndex++; | |
| return true; | |
| } | |
| } | |
| public void Reset() | |
| { | |
| throw new NotImplementedException(); | |
| } | |
| public void Dispose() | |
| { | |
| } | |
| public T Current | |
| { | |
| get | |
| { | |
| return m_Array[CurrentIndex]; | |
| } | |
| } | |
| object IEnumerator.Current => Current; | |
| internal Enumerator(ref ValueArraySegment<T> ar) | |
| { | |
| m_Array = ar.Array; | |
| CurrentIndex = ar.Offset - 1; | |
| EndIndex = ar.Offset + ar.Count; | |
| // IsEnd = false; | |
| // Offset = ar.Offset; | |
| } | |
| } | |
| public ValueArraySegment<T>.Enumerator GetEnumerator() | |
| { | |
| return new ValueArraySegment<T>.Enumerator(ref this); | |
| } | |
| IEnumerator<T> IEnumerable<T>.GetEnumerator() | |
| { | |
| return this.GetEnumerator(); | |
| } | |
| IEnumerator IEnumerable.GetEnumerator() | |
| { | |
| return this.GetEnumerator(); | |
| } | |
| } | |
| } |
debug build is slower than System.ArraySegment, but Release build much faster(10-20 times), why?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
implement IEnumerable and bug fixed