RobThree / NUlid

.Net ULID implementation
MIT License
364 stars 25 forks source link

Unsafe optimisations #24

Closed TimothyMakkison closed 1 year ago

TimothyMakkison commented 1 year ago

ToByteArray

Used Unsafe.WriteUnaligned to write the Ulid object to the array.

Method Mean Error StdDev Gen0 Allocated
UlidNew.ToByteArrayNew 6.823 ns 0.0565 ns 0.0529 ns 0.0255 40 B
Ulid.ToByteArray 12.540 ns 0.1201 ns 0.1003 ns 0.0255 40 B

CompareTo

Removed the usage of ToByteArray, instead directly accessing the fields of both objects, comparing each value.

Method Mean Error StdDev Gen0 Allocated
UlidNew.CompareUnequal 2.180 ns 0.0458 ns 0.0406 ns - -
UlidNew.CompareEqual 8.023 ns 0.0400 ns 0.0334 ns - -
Ulid.CompareUnequal 16.177 ns 0.0487 ns 0.0432 ns 0.0255 40 B
Ulid.CompareEqual 19.121 ns 0.0768 ns 0.0718 ns 0.0255 40 B

Equals

Used Unsafe.As to partially compare the Ulid internals as long values. This is a fallback for older versions.

Method Mean Error StdDev Gen0 Allocated
UlidNew.EqualsUnequal 1.0789 ns 0.0079 ns 0.0074 ns - -
UlidNew.EqualsEqual 0.9003 ns 0.0095 ns 0.0084 ns - -
Ulid.EqualsUnequal 25.5941 ns 0.0846 ns 0.0750 ns 0.0510 80 B
Ulid.EqualsEqual 32.5015 ns 0.2498 ns 0.2214 ns 0.0510 80 B

Get Time

Used bitwise hacks to shuffle the bytes into a padded long. Added a IsLittleEndian check because I suspect it wouldn't work on BE devices.

Method Mean Error StdDev Gen0 Allocated
Ulid.TimeNew 13.33 ns 0.051 ns 0.040 ns - -
Ulid.Time 30.80 ns 0.175 ns 0.155 ns 0.0408 64 B