This question has already been answered:

In general, I wanted to start optimizing something, for example, I want to start with the optimization of sorting algorithms.

How to find out the speed of sorting?

In fact, I need to know the time at which the program is executed. How to do it? I am writing in C #

Reported as a duplicate by Denis Bubnov , rdorn , PashaPash members c # Apr 28 '17 at 7:20 pm

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

2 answers 2

The direct answer to the question has already been given, but there is a feeling that much needs to be clarified.

First , there is no point in optimizing for the sake of optimization. Here is a quote from either Knutta or Dijkstra :

Premature optimization is the root of all (or most) programming problems.

Optimization should pursue strictly defined goals - to improve the performance of the application in a strictly defined number of times (determined by the user's needs) in strictly defined places where the current performance is lower than that needed by the application user. The realities are such that optimization can be done in a thousand different ways: changing the algorithm, changing the data structures, changing the means of the language, changing the language, and so on. There is no limit to perfection, so any optimization without a clear request from the user is time wasted. If there are no noticeable slacks in the application that prevent the application from performing business functions, then no optimization is really necessary.

Secondly , with regard to optimizations in .Net. For 90% of good code optimization is not needed at all. Of the remaining 10% in 90% of cases, only optimization of the algorithm is required. The remaining 10% of 10% may require different hacks, specific data structures, and so on. The latter category includes such loaded products with a large memory as compilers, ReSharper and similar things. By optimizing through the use of specific language tools and data structures, you inevitably reduce product maintenance . And then the question naturally arises of finding a balance between the readability of the code and the performance gain.

Thirdly , to be engaged in .Net optimization, you need to understand how the compiler works, how Jit works, you need to understand that different versions of Jit do different optimizations of your code and your super tweak, which runs faster on your system, in the end account under a different version of Jit may work slower. Various ingenious tips that pop up here and there on the Internet, such as:

  • Never use foreach , for - faster.
  • Instead of List<> use arrays, they are faster
  • Do not use Linq , it is slow.
  • Unwind the cycles (meaning, for example, raising to a power multiple of 4, where a *= b 4 times in each iteration)

it's all from the crafty one, for foreach , List and Linq are fast enough in most cases, and perversions, like unwinding cycles, can kill the compiler optimization, which could unwind this cycle without you.

Fourthly , it’s difficult to do benchmarking in .Net correctly for the same reasons as mentioned above for optimizing a lesson. The work of different versions of Jit, the need to “warm up” the method before the benchmark, the peculiarities of the work of the garbage collector, and so on - all this makes it difficult to obtain honest measurement data. The gold standard in this area is to use BenchmarkDotNet - the coolest library for benchmarking, authored by Andrey Akinshin from JetBrains, in fact, as I understand it, the product was written for internal use and in particular for the development of ReSharper. And even this framework needs to be used with the head.

I strongly advise you to watch this video in which Andrew himself talks about BenchmarkDotNet and the problems of measuring time in .Net.

I also advise you to look at the very recent report by Sergey Teplyakov on the optimization patterns in .Net applications.

In conclusion, I would like to say that if your goal is to simply implement several sorting algorithms and compare their performance on different data sets, then using Stopwatch can give you quite good results within a research task. But if the question is asked in the context of commercial software development, then there are already a lot of nuances concerning the expediency and correctness of the optimization carried out.

  • Worse, unwinding cycles on modern processors may be pessimizing: lkml.iu.edu/hypermail/linux/kernel/0008.2/0171.html - VladD
  • In the zero, premature pessimization is the root of all brakes in programming. - Alexander Petrov
  • one
    If you read the answer diagonally, then the eye will catch hold of four "ingenious advice." Ok, the reader will think, I'll go replace for with foreach. )) - Nick Volynkin
  • @NickVolynkin, indeed, corrected. - dm.dymov
  • "the need to warm up the method before the benchmark". Plus, but I want to note that for real-time tasks such as signal processing in this very real time, the speed of the "cold" method will play a role. - user239133

For accurate measurements with a run several times and calculating the average code execution time, you should use ready-made libraries, like BenchmarkDotNET , they have an excellent API, which is convenient, including, for embedding your benchmarks directly into your tests. A simpler way to measure execution speed without using standard libraries is the Stopwatch class from the System.Diagnostics namespace. You can measure the speed of code execution in this way:

 Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); //Замените на измеряемый код: Thread.Sleep(1800); stopwatch.Stop(); //Время, за которое выполнился Ваш код будет храниться в этой переменной: var elapsedTime = stopwatch.Elapsed; 

The value of the elapsedTime variable can be output to the console or to the Trace of your test - whatever you like. Again, if you need to measure the speed of code execution in many places, at what regularly, you can create a wrapper of the Stopwatch class to perform measurements using IDisposable and put the measured code into the using block.