Skip to main content
Code Review

Return to Question

Commonmark migration
Source Link

sw1: 10720019 ticks

sw2: 161726524 ticks

sw1: 10720019 ticks

sw2: 161726524 ticks

sw1: 10720019 ticks

sw2: 161726524 ticks

removed language from the title and thanks
Source Link
t3chb0t
  • 44.7k
  • 9
  • 84
  • 190

C# Validation Extension method performance

Thank you, in advance, for any advices :)

C# Validation Extension method performance

Thank you, in advance, for any advices :)

Validation Extension method performance

Source Link

C# Validation Extension method performance

I'm writing a simple set/framework of extension methods for argument/parameter validation. What I'm mostly concerned about, ATM is the performance, against the simpliest boilerplate

if(obj == null)
 throw new ArgumentNullException()

The framework I came up with is like that: The Validatable class packing the base object that will be validated through the ThrowIf() extension method.

public class Validatable<T>
{
 public T Value { get; }
 public Validatable(ref T argument)
 {
 Value = argument;
 }
}
public static Validatable<T> ThrowIf<T>(this T argument)
{
 return new Validatable<T>(ref argument);
}

And test methods themselves:

public static Validatable<T> IsNull<T>(this Validatable<T> argument) where T : class
{
 if (argument.Value == null)
 throw new ArgumentNullException();
 return argument;
}
public static Validatable<T> CollectionEmpty<T>(this Validatable<T> argument) where T: ICollection
{
 if (argument.Value.Count == 0)
 throw new ArgumentException();
 return argument;
}

This allows me to validate items with simple:

List<int> testList = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
testList.ThrowIf().IsNull().CollectionEmpty();

Everything was fine untill I decided to test, how it fares against the simple boilerplate.

int iNumber = 1000000000;
Stopwatch sw1 = new Stopwatch();
Stopwatch sw2 = new Stopwatch();
sw1.Start();
for (int i = 0; i < iNumber; ++i)
{
 if (testList == null)
 throw new ArgumentNullException();
 if (testList.Count == 0)
 throw new ArgumentException();
}
sw1.Stop();
sw2.Start();
for (int i = 0; i < iNumber; ++i)
{
 testList.ThrowIf().IsNull().CollectionEmpty();
}
sw2.Stop();
Console.WriteLine($"sw1: {sw1.ElapsedTicks} ticks");
Console.WriteLine($"sw2: {sw2.ElapsedTicks} ticks");

and the output was:

sw1: 10720019 ticks

sw2: 161726524 ticks

That's an order of magnitute difference. It was over 1,000,000,000 iterations, but still the difference is there.

I also tried with

public static void IsNullLite<T>(this T argument)
{
 if (argument == null)
 throw new ArgumentException();
}
public static void CollectionEmpty2Lite<T>(this T argument) where T : ICollection
{
 if (argument.Count == 0)
 throw new ArgumentException();
}

And it's result came somewhere in the middle with

sw3: 84165637 ticks

My questions are:

  1. Should I be concerned with the performance loss. It was +- 3sec vs 47secs on my PC, at 1,000,000,000 iterations. I do not plan to run it in such loops, over so many objects, but I was going to use it my game engine, where I have about 16ms per Update tick, to do much more than just validate some variables.
  2. Is there a better/faster way of doing it. Preferably, I'd like to pack the validation object into some sort of Validatable class, to not clutter the intelisense with dozens of validation methods.
  3. Is there some error on my part, in the way I tested it? I ran the tests in Debug mode with code optimalization turned off.

Thank you, in advance, for any advices :)

lang-cs

AltStyle によって変換されたページ (->オリジナル) /