Home > Articles > Details

AspNet Core Performance Tuning and Best Practices (C-Sharp 9 Enhancements)

C# Best Practices and Performance Tuning

  1. [NB]: The kind of data structure you use in the application matters when it comes to performance.
               Load the data from the Database into a Data structure and all Operations e.g. #UI ajax queries should query from the Data structure /lookups.

    - Always Sort your lists so that the BranchPredictor in CPU Core can predict when a for-loop and prefetch data from an L1, L2, and L3 (worst case fetch data from Memory Stick which takes couple nanoseconds).

  2. Three ways you could iterate through the #Collection
    collection.ForEach(a => {
    
    //ToDo
    })
    
    //Works well with Big Data Set
    Parallel.ForEach(collection, k => {
    //ToDo
    
    })
    
    //Works well with Big Data set
    collection.AsParallel().ForAll(k => {
    //ToDo
    })
    
    //Somewhat efficient way to loop through a list
    public void Loop(){
    
    foreach(var i in CollectionMarshal.AsSpan(myCollection)){
    //Do Something
    }
    }
    
    //Prefered way by using for loop since for loop is faster than for each loop
    //really fast, no memory allocation
    //This is only safe if you are not changing items in the list you are working with
    
    public void LoopBest(){
    var spane = CollectionsMarshal.AsSpan(myCollection);
    for(var i = 0; i < span.Lengthe; i++){
    var item = span[i];
    }
    }

2. Look in C# Class Destructors, basically, it reverses the Constructor Setters and gets Properties. e.g.

var (h,t, k,c) = myNiceClassConstructor();

3. How to Deallocate Object in a Class after Use
    - Use Structs (Value-based references "me" and "Me" are not equal)
    - Use Spans
    - Use Array Pooling
    - Never Load Data in memory you don't need, (The CPU fetches data it does not need from memory and then dumps it, garbage)
       If the CPU has a small Cache-Line, it is forced to go roundtrip to Memory to get the Data (that it does not even need).

4. CPU Operations
    - Prefetcher fetches data from Memory and Populates

5. Shorter tables Columns are faster than longer Table Columns this is because a Developer can restrict how many rows to retrieve by using a where clause.
6. Performance "How to deallocate Objects in Memory" or at least free memory up after usage
   - Make use of IDisposabled and dispose of objects in that class after usage
     - (My Own theory): Call GC to clean up regularly so objects allocated on the Stack can be collected and free up memory.
     - Use a "Using Statement" to implement IO operations, this frees up objects allocated on the Stack as well as the Heap after usage.
     - Use WeakReferences<MyClassObject> to work with Data Modals, this lets the GC know to collect that Object Allocation in memory after it has been used.
     e.g. Dictionary<int, WeakReference<MyDataModalClass>> _myDictionary = new();
     - [NB] You can allocate Memory in C# by using: private intPtr _head = Marshale.AllocGlobal(4);


 Tools to help Look into Memory Usage of an Application

   - Use DotPeek (app developed by JetBrain) to peak into Memory Usage
   -  Use Windows Built-In "Performance Monitor" to monitor Gen1, Gen2, and Gen3 Object Allocation in Memory


[Note] References
- If you are passionate about the Speed of your code, it is important that you consider, Cache/Memory
   hierarchy as you design and implement your algorithms and data structure
    - Jan Gray

-  Cache-Line is Key!! undoubtedly if you will make even a single error in data layout, you will get 100 x slower solutions! No Joke.
      - Dimtriy Vyukov



Reference:
1.




If you log in, you will be notified when someone leaves a comment.

Other users would like to know if this solution helped you.

Jack said:

Hi

Posted On: September 19, 2022 17:04:58 PM

© 2022 - ErnesTech - Privacy