Skip to content

Instantly share code, notes, and snippets.

View antonfirsov's full-sized avatar

Anton Firszov antonfirsov

View GitHub Profile
public interface IBytePacker<TColor>
where TColor: struct, IPackedPixel<TPacked>
{
// Better with Span<TColor> and Span<byte> if possible!
// Even better with a sourceRectangle parameter instead of sourceOffset
void PackBytes(TColor* source, byte[] dest, int destOffset, int count, ComponentOrder componentOrder);
}
#if SOLUTION_1
public static class TestUtilities
{
private static ConcurrentDictionary<string, TestFile> cache = new ConcurrentDictionary<string, TestFile>();
public static TestFile ToTestFile(this string fileName)
{
TestFile result;
if (!cache.TryGetValue(fileName, out result))
{
result = new TestFile(cache);
using System;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace AsyncMeetsUnsafe
{
[StructLayout(LayoutKind.Sequential)]
public class LocalityCriticalData : IDisposable
{
struct SuchMutableStruct
{
public Matrix99x42 SoState;
public bool IsInvalid { get; private set; }
public bool Invalidate()
{
IsInvalid = true;
}

Gif Encoder

I did not know that System.Drawing is a cheetah at gif, but let it be their problem! :) We need to find a better baseline then! What was made me to do this benchmark was seeing the OctreeeQuantizer's code. It's is very allocation-heavy. I think we can make a great improvement simply by doing a DOD refactor on the Octree class. It could be a very useful OOP vs DOD case study! However ... The numbers make me think there might be also an algorithmical issue. Is the whole algorithm running in O(PixelCount)? Does the tree have a depth limit? I can also pick this task if you want! :)

VS2017 and Span:

I think @dlemstra is concerned about VS2017. For me it's OK, we need to switch sooner or later anyway. But I'm also fine with a custom NuGet package. I already managed to pack the latest System.Runtime.CompilerServices.Unsafe with different class name to avoid collision with the official class.

Decoder

                            Method |   InputCategory |        Mean |    StdDev | Scaled | Scaled-StdDev | Allocated |

-------------------------------------- |---------------- |------------ |---------- |------- |-------------- |---------- | 'DecodeJpegMultiple - ImageSharp' | AllImages | 314.6764 ms | 1.7898 ms | 2.73 | 0.02 | 52.12 MB | 'DecodeJpegMultiple - System.Drawing' | AllImages | 115.1231 ms | 1.0570 ms | 1.00 | 0.00 | 5.4 MB | 'DecodeJpegMultiple - ImageSharp' | LargeImagesOnly | 228.7539 ms | 0.5567 ms | 3.10 | 0.02 | 28.32 MB | 'DecodeJpegMultiple - System.Drawing' | LargeImagesOnly | 73.7639 ms | 0.5337 ms | 1.00 | 0.00 | 4.91 MB | 'DecodeJpegMultiple - ImageSharp' | SmallImagesOnly | 78.7485 ms | 0.0961 ms | 1.87 | 0.02 | 23.78 MB | 'DecodeJpegMultiple - System.Drawing' | SmallImagesOnly | 42.0675 ms | 0.5665 ms | 1.00 | 0.00 | 489.48 kB |

Decoder

                            Method |   InputCategory |        Mean |    StdDev | Scaled | Scaled-StdDev | Allocated |

-------------------------------------- |---------------- |------------ |---------- |------- |-------------- |---------- | 'DecodeJpegMultiple - ImageSharp' | AllImages | 304.9019 ms | 0.5589 ms | 2.64 | 0.02 | 52.11 MB | 'DecodeJpegMultiple - System.Drawing' | AllImages | 115.4632 ms | 0.9450 ms | 1.00 | 0.00 | 5.4 MB | 'DecodeJpegMultiple - ImageSharp' | LargeImagesOnly | 224.3991 ms | 0.2855 ms | 3.04 | 0.04 | 28.32 MB | 'DecodeJpegMultiple - System.Drawing' | LargeImagesOnly | 73.8981 ms | 1.1043 ms | 1.00 | 0.00 | 4.91 MB | 'DecodeJpegMultiple - ImageSharp' | SmallImagesOnly | 76.4967 ms | 0.0444 ms | 1.85 | 0.01 | 23.78 MB | 'DecodeJpegMultiple - System.Drawing' | SmallImagesOnly | 41.4092 ms | 0.2310 ms | 1.00 | 0.00 | 489.48 kB |

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void CopyColorsTo(Span<byte> buffer, int stride, Block8x8F* tempBlockPtr)
{
this.TransformByteConvetibleColorValuesInto(ref *tempBlockPtr);
float* src = (float*)tempBlockPtr;
for (int i = 0; i < 8; i++)
{
buffer[0] = (byte)src[0];
buffer[1] = (byte)src[1];
public interface IPackedVector<TSelf>
where TSelf : IPackedVector<TSelf>
{
void CopyAllIntoVector4(Span<TSelf> source, Span<Vector4> destination);
}
                     Method | InputSize |          Mean |    StdErr |     StdDev | Scaled | Scaled-StdDev |

------------------------------- |---------- |-------------- |---------- |----------- |------- |-------------- | StandardArrays | 16 | 56.4556 ns | 0.2660 ns | 0.9953 ns | 1.00 | 0.00 | BatchedArrays | 16 | 57.7315 ns | 0.5755 ns | 2.3020 ns | 1.02 | 0.04 | StandardSpans | 16 | 78.0805 ns | 0.7939 ns | 3.4607 ns | 1.38 | 0.06 | StandardSpansMainCallIsInlined | 16 | 73.5502 ns | 0.3201 ns | 1.1978 ns | 1.30 | 0.03 | BatchedSpans | 16 | 79.5698 ns | 0.6289 ns | 2.4357 ns | 1.41 | 0.05 | BatchedPointers | 16 | 50.4953 ns | 0.2697 ns | 1.0093 ns | 0.89 | 0.02 | | | | | | | | StandardArrays | 64 | 241.3820 ns | 2.0609 ns |