A high-performance, extensible argument validation library.
От: _NN_ www.nemerleweb.com
Дата: 26.09.18 09:14
Оценка:
https://github.com/safakgur/guard

Что думаете насчёт этой библиотеки ?
Насколько CodeJam.Assertions лучше / хуже ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: A high-performance, extensible argument validation library.
От: Sinix  
Дата: 26.09.18 10:55
Оценка: 36 (3) :)
Здравствуйте, _NN_, Вы писали:

_NN>https://github.com/safakgur/guard


_NN>Что думаете насчёт этой библиотеки ?

_NN>Насколько CodeJam.Assertions лучше / хуже ?

high-performance, да?
См scaled.

                               Method |        Mean |     StdDev | Scaled | Scaled-StdDev | GcAllocations |
------------------------------------- |------------:|-----------:|-------:|--------------:|--------------:|
            Test00RunWithoutAssertion |    18.14 us |  0.1490 us |   1.00 |          0.00 |           0 B |
            Test01RunDefaultAssertion |    16.66 us |  0.5381 us |   0.92 |         0.031 |           0 B |
                    Test02CodeNotNull |    17.03 us |  0.1594 us |   0.94 |        0.0117 |           0 B |
             Test03CodeAssertArgument |    14.02 us |  2.1815 us |   0.76 |         0.115 |           0 B |
 Test04GuardAssertArgumentDocs_x0_001 | 1,789.07 us | 79.6902 us |  98.54 |          4.36 |      145.8 KB |
         Test05GuardAssertArgumentOpt |   105.01 us |  0.7094 us |   5.79 |         0.061 |           0 B |

Мне пришлось уменьшить количество запусков для штатного ассерта гуарда в 1000 раз, иначе он в шкалу не влезал.


        [CompetitionBaseline]
        [GcAllocations(0)]
        public string Test00RunWithoutAssertion()
        {
            var result = "";
            var count = Count;
            for (var i = 0; i < count; i++)
            {
                var arg = GetArg(i);
                result = arg;
            }

            return result;
        }

        [CompetitionBenchmark(0.71, 1.14)]
        [GcAllocations(0)]
        public string Test01RunDefaultAssertion()
        {
            var result = "";
            var count = Count;
            for (var i = 0; i < count; i++)
            {
                var arg = GetArg(i);

                if (arg == null)
                    throw new ArgumentNullException(nameof(arg));
                result = arg;
            }

            return result;
        }

        [CompetitionBenchmark(0.79, 3.40)]
        [GcAllocations(0)]
        public string Test02CodeNotNull()
        {
            var result = "";
            var count = Count;
            for (var i = 0; i < count; i++)
            {
                var arg = GetArg(i);

                Code.NotNull(arg, nameof(arg));
                result = arg;
            }

            return result;
        }

        [CompetitionBenchmark(0.63, 3.30)]
        [GcAllocations(0)]
        public string Test03CodeAssertArgument()
        {
            var result = "";
            var count = Count;

            for (var i = 0; i < count; i++)
            {
                var arg = GetArg(i);

                Code.AssertArgument(arg != null, nameof(arg), "Argument should be not null");
                result = arg;
            }

            return result;
        }

        [CompetitionBenchmark(85.01, 105.74)]
        [GcAllocations(0, 149309, BinarySizeUnit.Byte)]
        public string Test04GuardAssertArgumentDocs_x0_001()
        {
            var result = "";
            var count = Count / 1000; // <= !!!

            for (var i = 0; i < count; i++)
            {
                var arg = GetArg(i);

                Guard.Argument(() => arg).NotNull().NotEmpty();
                result = arg;
            }

            return result;
        }
        [CompetitionBenchmark(4.08, 6.61)]
        [GcAllocations(0)]
        public string Test05GuardAssertArgumentOpt()
        {
            var result = "";
            var count = Count;

            for (var i = 0; i < count; i++)
            {
                var arg = GetArg(i);

                Guard.Argument(arg, nameof(arg)).NotNull();
                result = arg;
            }

            return result;
        }
Re[2]: A high-performance, extensible argument validation library.
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 24.10.18 11:50
Оценка:
Здравствуйте, Sinix, Вы писали:

S>high-performance, да?


Это да. С другой стороны fluent API выглядит секси и уменьшает объем мусорного кода.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[3]: A high-performance, extensible argument validation library.
От: Sinix  
Дата: 24.10.18 14:16
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Это да. С другой стороны fluent API выглядит секси и уменьшает объем мусорного кода.


Спорно, как по мне. По крайней мере для среднестатистического кода.
Все "универсальные" сценарии должны быть скрыты за готовыми методами. Т.е. что под капотом — пользователя не колышет.
Все неуниверсальные обычно или элементарны, или настолько сложны, что их удобней записывать как if … throw.

Не, возможно бывают исключения, но я с таким не сталкивался.


Что интересно, автор сделал всё по уму (кроме перегрузки с exprTree) и оно может работать ещё быстрее с core 2+. Вот только большинство кода — не на Core.
Re[4]: A high-performance, extensible argument validation library.
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 24.10.18 17:42
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Спорно, как по мне. По крайней мере для среднестатистического кода.


Ну не знаю. Я регулярно натыкался на ситуации, когда по одному аргументу нужны 2-3 проверки. И каждый раз протаптывать nameof(myParam) — boring.

S>Все "универсальные" сценарии должны быть скрыты за готовыми методами. Т.е. что под капотом — пользователя не колышет.

S>Все неуниверсальные обычно или элементарны, или настолько сложны, что их удобней записывать как if … throw.

Чего то я не уловил связи. Я имел в виду вот такое:
Code
  .Argument(nameof(myParam))
  .NotNull()
  .InRange(...)
  .Assert(...);

Добавить такое вроде несложно, не трогая существующее API. А если в качестве retval будет структура, то и на перфомансе сказаться заметно не должно.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[5]: A high-performance, extensible argument validation library.
От: Sinix  
Дата: 24.10.18 18:07
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Ну не знаю. Я регулярно натыкался на ситуации, когда по одному аргументу нужны 2-3 проверки. И каждый раз протаптывать nameof(myParam) — boring.

А, ну да, есть такое. Ждём пропозала про [CallerExpressionArg]. Его несколько раз заводили, я тоже предлагал, но недодавил. Победитель — jamesqo.

AVK>Чего то я не уловил связи. Я имел в виду вот такое:

AVK>Добавить такое вроде несложно, не трогая существующее API. А если в качестве retval будет структура, то и на перфомансе сказаться заметно не должно.
Угу, понял, про что речь. Можно попробовать, но боюсь, эффекта особого не будет.
У safakgur/guard именно ref readonly структура, оптимизации (включая инлайн) для них емнип пока только в Core есть.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.