Skip to content

JaCraig/I-Got-Bored

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This is the repository for testing various speed improvements for Structure.Sketching and other libs. The results can be found below the conclussions section.

Conclussions

  1. When dealing with arrays of data inside of a method, use ArrayPool to allocate.

  2. Array.Copy is generally better for smaller arrays. Larger arrays (100,000+), Buffer.MemoryCopy seems to be a better option.

  3. For arrays, just treat them as arrays when iterating over them. IEnumerable, etc. slow them down.

  4. For arrays, foreach and for have no difference at this point in time.

  5. If you can, use Array.Sort and List.Sort. They're much faster than the alternatives.

  6. The various old optimizations like bitwise math are no longer effective.

  7. Unchecked math no longer seems to be substantially faster.

  8. Structs are much faster to create than classes. Setting or getting values is about the same though.

  9. For ConcurrentDictionary, use TryGetValue over an index or key lookup.

  10. For Dictionary, the type of the key matters. Long, uint, ulong, etc. are much faster than string.

  11. Dictionary is much faster than ConcurrentDictionary. Only use ConcurrentDictionary when you need to.

  12. Dynamic vs static typing, static is about 10x faster.

  13. Byte packing is faster than using an enum but it's about 4ns vs 2ns...

  14. Fields are slightly faster than properties in certain circumstances.

  15. Dictionary is generally faster than Hashtable if using an int as the key. Hashtable seems slightly faster when dealing with string as the key.

  16. Array.Copy and List.CopyTo are much faster at copying data over than other options.

  17. Arrays are much faster than alternatives for iteration.

  18. ++x or x++ makes no difference.

  19. Use 'is' instead of any of the clever other options if you can for determining the type of an object.

  20. If you can, use List.AddRange instead of List.Add.

  21. Using a for loop with Lists is the fastest approach.

  22. If you need something that looks like a Dictionary, then just use a Dictionary...

  23. If you're going to create a list of items, use AddRange instead of feeding them into the constructor.

  24. For small items, MemoryStream is better than RecyclableMemoryStream. For larger items, RecyclableMemoryStream is much better though.

  25. In terms of what is better (best to worst): Direct Method Call > Func(=>) > Func(Method) > Cached MethodInfo > new Func(=>) > new Func(Method).

  26. For null equality, use either is or ReferenceEquals.

  27. If you need to create an object, just use new. If you can't use new, compile/cache a lambda expression.

  28. Use partitioning when doing Parallel.ForEach if you need to worry about speed but note there will be a slight memory increase.

  29. If you're reading in a whole file, create the whole file in one go. This does not apply for instances where you are streaming the file or modifying portions of it.

  30. When you can, cache type info as it's not free.

  31. When you can, use a simple Contains instead of using Regex.

  32. using pointers into an array is slightly faster than a Span.

  33. stackalloc seems to be a speed boost at larger number of items.

  34. Do not use a statuc constructor if you don't need to. It gets called every time you call a method on the class.

  35. Use a StringBuilder instead of string concat. Memory and speed improvements for anything 100+ concatenations.

  36. If you're formatting a string, string concat is usually faster than things like string interpolation.

  37. If you can use a StringBuilderPool. Faster and memory improvements to be had.

  38. If you are going to replace a value in a string, use string.Replace instead of StringBuilder.Replace.

  39. String.Substring works slightly better than Span.Slice.

  40. Using string.Substring works better than Trim for small strings. Larger strings, Trim works better.

  41. Vector works better than dealing with straight struct, byte array, etc. in terms of speed. Memory increases though.

Results

BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19042.1165 (20H2/October2020Update)
Intel Core i7-9850H CPU 2.60GHz, 1 CPU, 12 logical and 6 physical cores
.NET SDK=5.0.303
  [Host]     : .NET 5.0.9 (5.0.921.35908), X64 RyuJIT
  DefaultJob : .NET 5.0.9 (5.0.921.35908), X64 RyuJIT

Allocation Strategy Tests

Method Count Mean Error StdDev StdErr Median Min Q1 Q3 Max Op/s Ratio RatioSD Rank Gen 0 Gen 1 Gen 2 Allocated
'Allocate as needed' 100 56.12 ns 1.134 ns 1.662 ns 0.309 ns 55.71 ns 53.39 ns 54.98 ns 57.10 ns 60.07 ns 17,817,409.3 1.00 0.00 2 0.0675 - - 424 B
ArrayPool 100 52.99 ns 1.049 ns 0.981 ns 0.253 ns 53.08 ns 51.72 ns 52.13 ns 53.51 ns 55.33 ns 18,870,851.6 0.93 0.03 1 - - - -
'Item from pointer to preallocated array 'pool'' 100 102.99 ns 1.567 ns 1.389 ns 0.371 ns 103.37 ns 101.09 ns 101.57 ns 103.84 ns 105.31 ns 9,709,521.8 1.80 0.05 4 - - - -
'Span from preallocated array 'pool'' 100 99.15 ns 1.173 ns 1.040 ns 0.278 ns 98.87 ns 97.79 ns 98.55 ns 99.43 ns 101.05 ns 10,085,768.4 1.73 0.04 3 - - - -
'Allocate as needed' 1000 534.01 ns 52.968 ns 154.511 ns 15.608 ns 482.06 ns 377.06 ns 402.84 ns 642.89 ns 939.27 ns 1,872,612.8 1.00 0.00 2 0.6413 - - 4,024 B
ArrayPool 1000 285.37 ns 4.622 ns 8.682 ns 1.309 ns 283.82 ns 276.96 ns 279.07 ns 286.53 ns 317.50 ns 3,504,181.7 0.61 0.13 1 - - - -
'Item from pointer to preallocated array 'pool'' 1000 1,006.20 ns 7.074 ns 6.271 ns 1.676 ns 1,005.33 ns 996.64 ns 1,003.08 ns 1,009.33 ns 1,018.39 ns 993,841.9 1.67 0.26 3 - - - -
'Span from preallocated array 'pool'' 1000 1,004.87 ns 16.886 ns 15.795 ns 4.078 ns 1,000.94 ns 985.84 ns 993.87 ns 1,015.74 ns 1,030.93 ns 995,155.5 1.65 0.26 3 - - - -
'Allocate as needed' 10000 3,618.63 ns 66.337 ns 110.834 ns 18.472 ns 3,594.44 ns 3,435.67 ns 3,551.89 ns 3,701.35 ns 3,909.66 ns 276,347.4 1.00 0.00 2 6.3248 - - 40,024 B
ArrayPool 10000 2,471.36 ns 22.579 ns 21.120 ns 5.453 ns 2,468.43 ns 2,447.23 ns 2,451.19 ns 2,478.83 ns 2,514.19 ns 404,635.3 0.67 0.02 1 - - - -
'Item from pointer to preallocated array 'pool'' 10000</