Do you know how to write fast C# code?
You may have already enrolled in a C# programming course, or learned the language at school or university. But here's a sobering fact: most courses only teach you how to write code, not how to write fast code.
The .NET Framework is huge. For any given problem there are many solutions, and it is not always clear which solution is the best choice.
Do you know how to write fast C# code?
You may have already enrolled in a C# programming course, or learned the language at school or university. But here's a sobering fact: most courses only teach you how to write code, not how to write fast code.
The .NET Framework is huge. For any given problem there are many solutions, and it is not always clear which solution is the best choice.
Did you know that adding strings together using the wrong Framework class will slow down your code by a factor of more than two hundred? And if you're not handling exceptions the right way, your code wil run a mind-boggling thousand times slower than normal.
Slow C# code is a big problem. Slow code on the web will not scale to thousands of users. Slow code will make your user interface unusable. Slow code will make your mobile apps languish in the app store.
Slow code is holding you back.
I can help you.
In a series of short lectures I will cover many common performance bottlenecks. I will introduce each problem, and then write a small test program to measure the baseline performance. Then I will demonstrate each possible solution, and benchmark how each solution measures up.
But there's more. I will also dive into Common Intermediate Code (CIL), the language that the C# compiler compiles to. If this sounds daunting, don't worry. The CIL language is actually very easy to read and understand. I'll take you through the basics in a quick 15-minute lecture.
Being able to read CIL code is a very useful skill that will help you avoid many performance pitfalls and give you a deeper understanding of the .NET Framework.
Why should you take this course?
You should take this course if you are a beginner or intermediate C# developer and want to take your skills to the next level. All my lectures are very easy to follow, and I explain all topics with clear code and many instructive diagrams.
Or you might be working on a critical section of code in a C# project, and need to make your code run as fast as possible. The tips and tricks in this course will help you immensely.
Or maybe you're preparing for a C# related job interview? This course will give you an excellent foundation to answer any performance-related questions they might throw at you.
In this lecture I explain how this course is organized and I describe each of the upcoming sections in detail.
In this lecture I will tell a bit more about myself, my career, and my motivation to become an online trainer.
In this lecture we're going to look at the theory behind code optimization. What exactly is code optimization, and when should you do it?
By the end of this lecture you will have learned the 5 strategies of code optimization, and at which stage in your project you should begin optimizing your code.
Many lectures in this course contain the actual source code I used to run my performance measurements. Feel free to download the code and follow along. And here's the good news: it doesn't matter if you have a Window, Mac or Linux computer. The code will run on all three operating systems.
In this lecture I demonstrate how my solutions and projects run on all operating systems. I will show you how to build and run the source code on a Mac, on Linux and in Visual Studio running on Windows 8.
At the end of this lecture you will have learned that .NET code is portable and can run on at least five different operating systems.
Welcome to the Fundamentals of the .NET Framework section. I will give a quick introduction on how the section is organized before we get started.
Test your knowledge of the stack, If you have no trouble answering all of the questions, feel free to skip to the next lecture.
Many lectures in this course use memory diagrams to show how objects and variables are laid out on the stack and the heap. This lesson will lay down some groundwork and explain in detail what the stack is for, and how data on the stack is laid out in memory.
After completing this lecture you will have learned which data is stored on the stack and what happens when this data goes out of scope. Finally, you will have seen a Stack Overflow exception, and know how to avoid this exception in your own code.
If you are already familiar with the internal workings of the stack in the .NET Framework, feel free to skip this lecture.
Test your knowledge of the heap, If you have no trouble answering all of the questions, feel free to skip to the next lecture.
Many lectures in this course use memory diagrams to show how objects and variables are laid out on the stack and the heap. This lesson will lay down some groundwork and explain in detail what the heap is for, and how data on the heap is laid out in memory.
After completing this lecture you will have learned which data is stored on the heap and what happens when variables that refer to this data go out of scope. Finally, you will be able to explain what the 'Garbage collection' process does.
If you are already familiar with the internal workings of the heap in the .NET Framework, feel free to skip this lecture.
Test your knowledge of value types, If you have no trouble answering all of the questions, feel free to skip to the next lecture.
A popular question that often comes up in job interviews is: "what is the difference between a value type and a reference type?"
This lecture looks at value types in detail. What are value types, how do they store their data, and what happens when value types are assigned or compared? After completing this lecture you will be able to answer all of these questions with ease.
Test your knowledge of reference types, If you have no trouble answering all of the questions, feel free to skip to the next lecture.
A popular question that often comes up in job interviews is: "what is the difference between a value type and a reference type?"
This lecture looks at reference types in detail. What are reference types, how do they store their data, and what happens when reference types are assigned or compared? After completing this lecture you will be able to answer all of these questions with ease.
Test your knowledge of boxing and unboxing, If you have no trouble answering all of the questions, feel free to skip to the next lecture.
Value types and reference types are both derived from the same common base class "Object". This is a nice feature of the .NET Framework, but behind the scenes it creates some problems for the runtime environment because reference types can never exist on the stack.
In this lecture you will learn how .NET uses a cool trick called "Boxing" to get around this problem. After completing the lecture you will be able to explain what boxing and unboxing is, and why it is neccesary.
Test your knowledge of immutable strings, If you have no trouble answering all of the questions, feel free to skip to the next lecture.
Strings in .NET are said to be "immutable". But what does that actually mean? And what are the advantages of immutable strings?
In this lecture, we will look at immutable strings in detail. You will learn how the immutability is implemented, why it is advantageous, and what the consequences are when assigning and comparing strings.
Congratulations on finishing this section. This is a recap of what we have learned.
Welcome to the crash course in Common Intermediate Language. I will give a quick introduction on how the section is organized before we get started.
Many lectures in this course dive deep into compiled C# code and show you how certain Common Intermediate Language (CIL) instructions can be responsible for performance problems in your code.
This lesson will lay down some groundwork and describe how the Intermediate Language environment actually works. We will look at a simple C# program, compile it to CIL code and then identify and describe every CIL instruction in the compiled code.
By the end of the lecture you will have learned what the most common CIL instructions do, and you will be able to read and understand a simple compiled C# program.Congratulations on finishing this section. This is a recap of what we have learned.
Test your knowledge of Common Intermediate Language with this quiz.
Welcome to the basic optimizations section. I will give a quick introduction on how the section is organized before we get started.
Value types and reference types are both derived from the same common base class "Object". This creates some problems for the runtime environment because reference types can never exist on the stack. The.NET Framework gets around this problem by uses a special operation called "Boxing".
In this lecture you will learn the performance overhead of the boxing operation. We will look at several classes in the .NET Framework that perform a lot of boxing operations in the background, and I will show you some alternatives that do not use boxing.
In a head-to-head we will compare the performance of code that uses boxing and code that does not. You will see exactly how much overhead the boxing operation introduces.
After completing this lecture you will have learned how large the boxing performance overhead is, and how to avoid this performance penalty by using classes in the .NET Framework that avoid boxing.
In the Fundamentals section you learned that strings in .NET are immutable. This introduces some performance overhead when modifying strings, especially when done in a loop.
In this lecture we are going to look at string concatenation. Both the String and the StringBuilder class go head-to-head, and you will see how both measure up for a range of concatenation operations.
If you thought that the StringBuilder class is always faster than the String class, then the results may surprise you.
The .NET Framework has a bewildering array of collection classes. Arrays, Collections, ArrayLists, Dictionaries, generic lists... the list goes on and on. Which class should you use if you simply want to store a collection of values?
In this lecture we look at three collection classes in .NET: the ArrayList, the generic List, and the array. We'll measure the performance of each one, and identify the best choice for mission critical code.
In the previous lecture you learned that arrays have an excellent performance in the .NET Framework. But there are three types of arrays: 1-dimensional, multidimensional, and jagged arrays. How do they measure up?
In this lecture you will learn the difference in performance between the three array types. I will also show you a special technique called 'array flattening', to transform a multidimensional array into a 1-dimensional array.
After completing this lecture you will be able to identify the fastest and the slowest array type, and you will be able to describe the performance benefits of array flattening.
How large do you think the performance overhead is for throwing and catching an exception? In this lecture you'll find out. I will show you a program that rapidly throws and catches an exception, and we'll measure exactly how many times per second the .NET Framework can throw an exception.
Next we'll compare int.Parse and int.TryParse, and deliberately feed invalid data into these methods to measure the overhead of the FormatExceptions being thrown. You will learn which of these two methods has the best performance.
Finally we will do the same for the Dictionary<Tkey, Tvalue> class: feed invalid keys to a dictionary and measure the overhead of the KeyNotFound exception.
After completing this lecture you will be aware of the performance overhead of throwing and catching exceptions, and you will have learned several strategies for avoiding invalid operations in your code without having to resort to a try - catch block.
There are two types of for loops in .NET: the for() loop, and the foreach() loop. What is the difference between the two?
I will show you the performance for each of these two loop types, for generic lists, the ArrayList, and regular arrays. After completing this lecture you will know exactly when it is worthwhile in terms of performance to refactor a foreach loop into a for loop.
Test your knowledge of basic optimisations by taking this quiz.
Welcome to the intermediate optimizations section. I will give a quick introduction on how the section is organized before we get started.
The .NET Garbage Collector is responsible for cleaning up all dereferenced objects on the heap. In this lecture we are going to take a long hard look at its internal architecture.
I will show you how the Garbage Collector uses a mark-and-sweep cycle to periodically clean the heap, how it uses generations to sort objects into short-living and long-living groups, and how it is specifically optimized for handling large objects.
After completing this lecture you will be able to describe in detail how the Garbage Collector works. You will also be aware of the assumptions it makes about object sizes and lifetimes.
In this lecture we're going to look at a couple of specific performance improvements you can make to your code, that will help you work with the Garbage Collector instead of against it.
We will look in detail at the assumptions the Garbage Collector makes about the size and lifetime of the objects in your code, and how you can take advantage of these assumptions by carefully designing your objects.
After completing this lecture you will have a number of recipes at your disposal for creating fast and efficient code that works in harmony with the Garbage Collector.
In this lecture we are going to take a closer look at delegates, which are special .NET types that represent a method call. I will show you how you can use delegates to call either a single method (unicast), or multiple methods in one go (multicast).
Is it okay to use delegates in your code? Is there a measurable performance difference between unicast and multicast delegates? After completing this lecture you will have all the answers.
Class factories are specialised classes that construct other class instances on demand, based on external configuration information.
It's common to use the Activator class in the Reflection namespace to implement a class factory. But did you know that Activator is close to a 100 times slower than compiled code? What if you need to construct millions of objects at runtime, without knowing their type in advance, and top performance is crucial?
Fortunately there is a solution. I am going to show you a very cool class factory implementation that totally outperforms the Activator class.
Test your knowledge of intermediate optimizations by taking this quiz.
Welcome to the advanced optimizations section. I will give a quick introduction on how the section is organized before we get started.
Arrays are reference types, and therefore they will always be allocated on the heap. But did you know there is a special keyword in C# for allocating an array on the stack?
In this lecture you will learn how to allocate and use arrays on the stack. I will show you a program that uses a stack-based array and a heap-based array, and both arrays will go head-to-head in a performance showdown.
Is a stack-allocated array worth the trouble? Watch the lecture and find out.
Languages like C and C++ have rich pointer support and let you manipulate data directly in memory. But did you know the C# language also has support for pointer operations?
In this lecture I will show you how to enable pointer support in C#. We will look at a simple image processing algorithm for converting an image into grey-scale. Two implementations go head-to-head in a performance showdown: one using high level GetPixel and SetPixel methods, and another that uses a pointer to the image data to modify the pixels directly.
You will learn the performance of both approaches and discover which one is the fastest. After completing this course you will be able to answer the question: "should you use pointers in C#?"
In this lecture we revisit the grey-scale conversion algorithm from the previous lesson. The previous lecture compared a pointer-based algorithm with one that used high-level GetPixel and SetPixel methods. An easy win for the pointers. But how do pointers fare on a more level playing field?
In this lecture we will look at the grey-scale conversion algorithm operating on a 1-dimensional byte array. We will compare three implementations of the conversion algorithm: one using standard array indexing, and two implementations that use byte pointers to directly manipulate the contents of the array. Which will be the fastest?
After completing this lecture you have learned once and for all if pointers can outperform an array in C#.
Test your knowledge of advanced optimizations by taking this quiz.
In this lecture I would like to thank you for finishing the course and offer some final words.
OpenCourser helps millions of learners each year. People visit us to learn workspace skills, ace their exams, and nurture their curiosity.
Our extensive catalog contains over 50,000 courses and twice as many books. Browse by search, by topic, or even by career interests. We'll match you to the right resources quickly.
Find this site helpful? Tell a friend about us.
We're supported by our community of learners. When you purchase or subscribe to courses and programs or purchase books, we may earn a commission from our partners.
Your purchases help us maintain our catalog and keep our servers humming without ads.
Thank you for supporting OpenCourser.