КОМЕНТАРІ •

  • @omarbousbia6916
    @omarbousbia6916 3 роки тому +1

    Great tips,,, thank you

  • @johnfrian
    @johnfrian 3 роки тому +3

    Honestly, the best LINQ performance tip is to not use LINQ. In many cases it's a compromise between readability vs performance, choosing between LINQ and a custom loop that does exactly what you need. There are, of course, cases where LINQ provides nice additions (e.g. null-checks) without doing anything too crazy on top of that (like .Any()). Just be mindful when using methods like GroupBy() which can be up to 9 times slower than a simple foreach.

    • @LevelUppp
      @LevelUppp 3 роки тому

      Watch the other videos :) you can have your cake an eat it too. It requires some work but you can get LINQ at zero cost, but not out of the box you have to improve and re-implement methods and operators.

  • @frankroos1167
    @frankroos1167 3 роки тому

    For the ToLower bit: I am missing the option of first uniting the collections to be filtered by into a single one. That should also limit the number of ToLower calls to 1.

  • @edwardevlogiev4087
    @edwardevlogiev4087 3 роки тому +2

    Hey, thumbs up for all the effort.
    I would like to point out that LINQ is designed for readability, not performance, and it's excellent in situations where you need to apply complex transformations over not very big collections.
    Optimizing where optimizations are not need is, in the best case, harmless.

    • @LevelUppp
      @LevelUppp 3 роки тому +1

      True, although one can have it's cake and eaten with LINQ by improving some of the operators by using structs, value delegates, de virtualisation, better branching code etc.
      My next couple of videos in the series show how to achieve this with LINQ, plus there are frameworks that do this out of the box as well:
      ♦ github.com/NetFabric/NetFabric.Hyperlinq
      ♦ github.com/reegeek/StructLinq

    • @edwardevlogiev4087
      @edwardevlogiev4087 3 роки тому +1

      @@LevelUppp Yup, certainly and there's nothing wrong with that. My argument is mostly aimed at beginners when they fall into the trap of feeling they MUST optimize or they are doing it wrong.

  • @David-id6jw
    @David-id6jw 3 роки тому +1

    Filter_ToLower_04 has another difference from the first three: It doesn't return the result. So it doesn't have to copy the reference back to/off the stack, which means less memory access, etc. I'm pretty sure that's why it's faster than version 03, and not because of the change in comparison order.
    Though you're still correct that the number of comparisons in the respective lists will have an impact on a more elaborate app.

    • @LevelUppp
      @LevelUppp 3 роки тому

      While pushing and pooping the stack does have an impact, it's incredibly fast, in this specific case it was the branch order since the data is skewed in such a way that the branch order does make an impact.
      That missing return was an accidental omission on my part and I've fixed it later.

  • @atmanirbharbharat
    @atmanirbharbharat 2 роки тому

    i there any wy to replacement of .contains. for large DB performance issue

  • @nvtmjfan
    @nvtmjfan 2 роки тому

    What is diff between method 3 and 4.

  • @therealxunil2
    @therealxunil2 3 роки тому +3

    I would emphasize the point that if you're examining millions of records, those 5ms in your test case will add up to a significant savings in time.

    • @LevelUppp
      @LevelUppp 3 роки тому

      The problem with that is that if you're around ~5% better it would be good to do a statisticalsignificance test to be sure that your gains are not just random noise.

  • @sanjayi6245
    @sanjayi6245 4 роки тому +3

    Very good video.

    • @LevelUppp
      @LevelUppp 4 роки тому +1

      Thanks! :)

    • @sanjayi6245
      @sanjayi6245 4 роки тому

      @@LevelUppp Can you tell me what font you are using in Visual Studio.

    • @LevelUppp
      @LevelUppp 4 роки тому

      @@sanjayi6245 It's consolas, I've got it by default.

    • @sanjayi6245
      @sanjayi6245 4 роки тому +1

      @@LevelUppp Ah. Okay. Anyway continue what you are doing. Cheers

  • @Bjarkediedrage
    @Bjarkediedrage 4 роки тому +1

    When trying to do ECS in c# some time ago, I hit a wall when trying to provide a nice way of enumerating quickly throught various data buckets in an easy way. Mainly because C# can't inline lambdas. (Yet??).
    For instance:
    void IterateOnDataBuckets_Slow(Action iterator)
    {
    for (...) { // Imagine a more complex iterator.
    iterator(someData[i]);
    }
    }
    interface DataBucketIterator {
    void Evaluate(ref Data data);
    }
    void IterateOnDataBuckets_SillSlow(DataBucketIterator iterator)
    {
    for (...) { // Imagine a more complex iterator.
    iterator.Evaluate(ref someData[i]); // still quite slow.
    }
    }
    void IterateOnDataBuckets_FastAndInlineable(T iterator) where T : DataBucketIterator
    {
    for (...) { // Imagine a more complex iterator.
    iterator.Evaluate(someData[i]); // Since it's know what T is, it's able to inline this function.
    }
    }
    But of course, having to write a type just to enumearte the data, so I stopped the ECS experiement there. Wondering if you have any experience with that sort of problem?

    • @LevelUppp
      @LevelUppp 4 роки тому

      Lambdas that need to capture context usually cannot be inlined since the compiler will create a class and push all of the captured variables there, thus inlining is out of the question. This is a current limitation of the compiler since in a lot of cases such treatment shouldn't be needed.
      Then there's a general problem that delegates cannot be inlined at the calle site yet another limitation that could be improved.
      What I would do is a struct that describes the iterator this can be created with an lambda function but it returns a struct that describes what needs to be done, this would let you solve the problem, the matching engine would be a bit more complicated (and perhaps limited) but you would see performance gains.

    • @LevelUppp
      @LevelUppp 4 роки тому

      If you need to iterate quickly you should pay the most attention to the data layout of your components, inlining while help should not be the primary cost. Are you using SOA for components? Have you tried doing SOA with SIMD? For well crafted components and systems using the SOA over SIMD is usually very fast.

    • @LevelUppp
      @LevelUppp 4 роки тому

      Sorry one last question :) What C# compiler are you using? If it's the Unity compiler things are a bit different there, and if it's the Burst Compiler thins are even more extreme and with the C#9 on the horizon you could try using function pointers but the Unity toolchain is even faster when using SIMD.

    • @Bjarkediedrage
      @Bjarkediedrage 4 роки тому

      @@LevelUppp It was mostly an experiment to see how close I could get to c/c++ performance. I've not tried and use SIMD before really, but I've been wanting to since seeing your videos.

    • @Bjarkediedrage
      @Bjarkediedrage 4 роки тому

      @@LevelUppp Yeah, it's really cool how fast they've gotten things with burst. They also inline the delegates, (but I have had some bugs with scope and capturing variables^^). Okay, I was not aware of C# 9 function pointers, that is awesome!

  • @ProfessorCodemunkie
    @ProfessorCodemunkie 4 роки тому

    With the let example I wonder what the performance would be like using LINQ method syntax i.e. transactions.Where(t => { var nameLowerCase = t.Name.ToLower(); if.... }).Select(...

    • @LevelUppp
      @LevelUppp 4 роки тому

      Not sure we can check :) but I assume it would be faster?

  • @abdelrhmanahmed1378
    @abdelrhmanahmed1378 2 роки тому

    in groupByLookup you dont deal with collisions,and when i see the imp of groupBy provided by Microsoft it look very similar to yours , so why the performance gap is hug ?!

  • @JacekGasiorowski
    @JacekGasiorowski 4 роки тому +11

    Hello, I might be wrong but your example with GroupBy_O1 might be totally incorrect.
    By using your group by LINQ query you only building expression tree which is not materialised anywhere (you are not calling .ToList() after query or just .Count()) so your mesurement only shows how long it takes to build the LINQ expression for the runtime. I is never executed. I tried that example myself and with .ToList() call it takes almost 9 times more time than withou it. I think it might be a mistake on your side because you used .ToList() call in examples with filtering

    • @LevelUppp
      @LevelUppp 4 роки тому +2

      You're right, thanks!

    • @LevelUppp
      @LevelUppp 4 роки тому +1

      I'll correct that in another video

    • @LevelUppp
      @LevelUppp 4 роки тому +2

      And here I was thinking that there's a saving grace for LINQ but no :( although it's sill not that bad in performance numbers but my Lookup absolutely destroys LINQ.

    • @JacekGasiorowski
      @JacekGasiorowski 4 роки тому

      @@LevelUppp Exactly :) good job :)

    • @LevelUppp
      @LevelUppp 4 роки тому

      @@JacekGasiorowski No that makes me sad since I wanted to love the built in Lookup ;-(

  • @psychotrout
    @psychotrout 3 роки тому +2

    LINQ query syntax is very ugly to read, the method chain version is much more readable and modern in my opinion:
    transactions.Where(x => ...).Selec(x => x...);

  • @CHITRANSHSHARMA
    @CHITRANSHSHARMA 3 роки тому

    I am 639th subscriber

  • @user-vi7xn1tj9f
    @user-vi7xn1tj9f 2 місяці тому

    Great video. I would only recommend to work on a proper naming convention, as you named all of the tested methods with quite generic (nothing saying) names.

  • @theincredibleillmo9385
    @theincredibleillmo9385 3 роки тому +6

    Great tips, just be aware about coughing all the time, it is really annoying when someone uses headphones.

    • @Cerstani
      @Cerstani 3 роки тому

      If you thought that was annoying, you should NEVER subject yourself to a DarkSydePhil (DSPGaming) video..

  • @danflemming3553
    @danflemming3553 4 роки тому +8

    At 11:50 where you talk about LINQ's Last() method, you say that LINQ doesn't check to see if the enumerable is actually a list.
    That's incorrect. LINQ does that actually:
    github.com/microsoft/referencesource/blob/master/System.Core/System/Linq/Enumerable.cs#L1091
    And in the next line, you can see it actually calls the index:
    if (count > 0) return list[count - 1];
    github.com/microsoft/referencesource/blob/master/System.Core/System/Linq/Enumerable.cs#L1093
    More importantly, your code works faster also because you don't check like LINQ to see if the list has any elements in it before accessing the index. This isn't the main cause why your code is faster, but it's important to note.
    The performance penalties you're seeing are of different reasons, not because LINQ doesn't check if the instance is a list

    • @LevelUppp
      @LevelUppp 4 роки тому +1

      Yeah the old version of LINQ didn't do that check. The new version indeed does the check.
      The type check is what's slowing it down, and since it's using the interface version all calls are considered VCalls and it's another tiny penalty that is relevant at scale.
      Thanks ❤️

    • @danflemming3553
      @danflemming3553 4 роки тому +2

      Don't get me wrong, your content is OK, LINQ is slower but some of the reasons you say why LINQ is slower not all of them are correct. Keep up the good work and thanks

    • @LevelUppp
      @LevelUppp 4 роки тому +2

      @@danflemming3553 Hey, I'm not bothered or anything like that. I think you're doing great work correcting all of the mistakes that I've made. This will lead to better quality videos, more discussion, small arguments, corrections and everyone will benefit at the end. Thanks :)

    • @danflemming3553
      @danflemming3553 4 роки тому +2

      @@LevelUppp Wow, great attitude dude 👍🏻 Many don't understand that and would be offended! It's exactly my point, the idea is to improve, we all need to learn and improve. I have a lot of things I need to improve myself and your videos are great!

    • @danflemming3553
      @danflemming3553 4 роки тому

      @@LevelUppp Actually Last() works like that at least since 2014, that's at least 6 years ago 🙂:
      github.com/microsoft/referencesource/blob/9da503f9ef21e8d1f2905c78d4e3e5cbb3d6f85a/System.Core/System/Linq/Enumerable.cs#L967

  • @m057d0p3
    @m057d0p3 3 роки тому

    Why dont you use BenchmarkDotnet to measure?

    • @LevelUppp
      @LevelUppp 3 роки тому +1

      Too slow to measure. It takes an average of ~1-5 minutes per run.
      However new videos include Benchmark.NET as
      well either by having it already pre-computed or by speeding up the video 15x times when the benchmark runs.

  • @jfaquinojr
    @jfaquinojr 3 роки тому +2

    Anybody else cringe when he coughs?
    Hope OP is ok

    • @LevelUppp
      @LevelUppp 3 роки тому

      Had a Flu when I was recording this, sorry :)