41,99 €
Create fast, scalable, and high performance applications with C#, ASP.NET Core 1.0, and MVC 6
This book is for ASP.NET and C# developers who have experience with the MVC framework for web application development and are looking to deploy applications that will perform well in live production environments. These could be virtual machines or hosted by a cloud service provider such as AWS or Azure.
ASP.NET Core is the new, open source, and cross-platform, web-application framework from Microsoft. It's a stripped down version of ASP.NET that's lightweight and fast. This book will show you how to make your web apps deliver high performance when using it.
We'll address many performance improvement techniques from both a general web standpoint and from a C#, ASP.NET Core, and .NET Core perspective. This includes delving into the latest frameworks and demonstrating software design patterns that improve performance.
We will highlight common performance pitfalls, which can often occur unnoticed on developer workstations, along with strategies to detect and resolve these issues early. By understanding and addressing challenges upfront, you can avoid nasty surprises when it comes to deployment time.
We will introduce performance improvements along with the trade-offs that they entail. We will strike a balance between premature optimization and inefficient code by taking a scientific- and evidence-based approach. We'll remain pragmatic by focusing on the big problems.
By reading this book, you'll learn what problems can occur when web applications are deployed at scale and know how to avoid or mitigate these issues. You'll gain experience of how to write high-performance applications without having to learn about issues the hard way.
You'll see what's new in ASP.NET Core, why it's been rebuilt from the ground up, and what this means for performance. You will understand how you can now develop on and deploy to Windows, Mac OS X, and Linux using cross-platform tools, such as Visual Studio Code.
Starting with a drill down into the nuts and bolts of various performance parameters, you will get an understanding of the ASP.NET MVC 6 framework with the help of rich code-based examples that will equip you to build highly scalable and optimized applications.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 388
Veröffentlichungsjahr: 2016
Copyright © 2016 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: June 2016
Production reference: 1170616
Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.
ISBN 978-1-78588-189-3
www.packtpub.com
Author
James Singleton
Copy Editor
Priyanka Ravi
Reviewer
Jason De Oliveira
Project Coordinator
Suzanne Coutinho
Commissioning Editor
Edward Gordon
Proofreader
Safis Editing
Acquisition Editor
Chaitanya Nair
Indexer
Mariammal Chettiyar
Content Development Editor
Merint Thomas Mathew
Graphics
Kirk D'Penha
Technical EditorKunal Chaudhari
Production Coordinator
Melwyn Dsa
"The most amazing achievement of the computer software industry is its continuing cancellation of the steady and staggering gains made by the computer hardware industry."
--Henry PetroskiWe live in the age of distributed systems. Computers have shrunk from room-sized industrial mainframes to embedded devices that are smaller than a thumbnail. However, at the same time, the software applications that we build, maintain, and use every day have grown beyond measure. We create distributed applications that run on clusters of virtual machines scattered all over the world, and billions of people rely on these systems, such as e-mail, chat, social networks, productivity applications, and banking, every day. We're online 24 hours a day, seven days a week, and we're hooked on instant gratification. A generation ago, we'd happily wait until after the weekend for a cheque to clear, or allow 28 days for delivery. Today, we expect instant feedback, and why shouldn't we? The modern web is real-time, immediate, on-demand, built on packets of data flashing around the world at the speed of light, and when it isn't, we notice. We've all had that sinking feeling... you know, when you've just put your credit card number into a page to buy some expensive concert tickets, and the site takes just a little too long to respond. Performance and responsiveness are a fundamental part of delivering great user experience in the distributed age. However, for a working developer trying to ship your next feature on time, performance is often one of the most challenging requirements. How do you find the bottlenecks in your application performance? How do you measure the impact of those problems? How do you analyze them, design and test solutions and workarounds, and monitor them in production so that you can be confident that they won't happen again?
This book has the answers. Inside, James Singleton presents a pragmatic, in-depth, and balanced discussion of modern performance optimization techniques, and how to apply them to your .NET and web applications. Starting from the premise that we should treat performance as a core feature of our systems, James shows how you can use profiling tools such as Glimpse, MiniProfiler, Fiddler, and Wireshark to track down the bottlenecks and bugs that cause your performance problems. He addresses the scientific principles behind effective performance tuning, monitoring, instrumentation, and the importance of using accurate and repeatable measurements when you make changes to a running system to try and improve performance.
This book goes on to discuss almost every aspect of modern application development: database tuning, hardware optimisations, compression algorithms, network protocols, and object-relational mappers. For each topic, James describes the symptoms of common performance problems, identifies the underlying causes of those symptoms, and then describes the patterns and tools that you can use to measure and fix these underlying causes in your own applications. There's in-depth discussion of high-performance software patterns such as asynchronous methods and message queues, accompanied by real-world examples showing you how to implement these patterns in the latest versions of the .NET framework. Finally, James shows how you can not only load test your applications as a part of your release pipeline, but you can continuously monitor and measure your systems in production, letting you find and fix potential problems long before they start upsetting your end users.
When I worked with James here at Spotlight, he consistently demonstrated a remarkable breadth of knowledge, from ASP.NET to Arduinos, from Resharper to resistors. One day, he'd build reactive frontend interfaces in ASP.NET and JavaScript, the next he'd create build monitors by wiring microcontrollers into Star Wars toys, or working out how to connect the bathroom door lock to the intranet so that our bicycling employees could see from their desks when the office shower was free. After James moved on from Spotlight, I've been following his work with Cleanweb and Computing 4 Kids Education. He's one of those rare developers who really understands the social and environmental implications of technology—that whether it's delivering great user interactions or just saving electricity, improving your systems' performance is a great way to delight your users. With this book, James has distilled years of hands-on lessons and experience into a truly excellent all-round reference for .NET developers who want to understand how to build responsive and scalable applications. It's a great resource for new developers who want to develop a holistic understanding of application performance, but the coverage of cutting-edge techniques and patterns means it's also ideal for more experienced developers who want to make sure they're not getting left behind. Buy it, read it, share it with your team, and let's make the web a better place.
Dylan Beattie
Systems architect
REST evangelist, technical speaker
Co-organizer of the London .NET User Group
James Singleton is a British software developer, engineer, and entrepreneur, who has been writing code since the days of the BBC Micro. His formal training is in electrical and electronic engineering, yet he has worked professionally in .NET software development for nearly a decade.
He is active in the London start-up community and helps organize Cleanweb London events for environmentally conscious technologists. He runs Cleanweb Jobs, which aims to help get developers, engineers, managers, and data scientists into roles that can help tackle climate change and other environmental problems. He also does public speaking, and he has presented talks at many local user groups, including at the Hacker News London meet up.
James holds a first class degree (with honors) in electronic engineering with computing, and he has designed and built his own basic microprocessor on an FPGA along with a custom instruction set to run on it. He is also a Science, Technology, Engineering, and Mathematics (STEM) ambassador, who encourages young people to study these fields.
James contributes to and is influenced by many open source projects, and regularly uses alternative technologies, such as Python, Ruby, and Linux. He is enthusiastic about the direction that Microsoft is taking .NET in and their embracing of open source practices.
He is particularly interested in hardware, environmental, and digital rights projects and is keen on security, compression, and algorithms. When not hacking on code, or writing for books and magazines, he enjoys walking, skiing, rock climbing, traveling, brewing, and craft beer.
James has gained varied skills from working in many diverse industries and roles, from high performance stock exchanges to video encoding systems. He has worked as a business analyst, consultant, tester, developer, and technical architect. He has a wide range of knowledge, gained from big corporates to startups, and a lot of places in between. He has first-hand experience of the best and worst ways of building high performance software.
You can read his blog at unop.uk.
I would like to thank all of my friends and family for being so supportive while I've been working on this book. I would especially like to thank my dad for getting me into technology at a young age, and Lou for her limitless enthusiasm and positivity. I would also like to thank Dylan for writing the foreword to this book.
Writing a book is much harder work than most people probably imagine, and I couldn't have done it without the constant encouragement. Many sacrifices needed to be made and I thank everyone for their understanding. Sorry for all the events that I've had to miss and to anyone who I've forgotten to thank here.
I would also like to acknowledge Radio Paradise for keeping me sane from the noise of the inconsiderate constructors next door. Finally, I apologize in advance to my British (or Aussie, Kiwi, Canadian, and so on) readers for any of the less-correctly spelled words used in this book.
Jason De Oliveira works as CTO for MEGA International (http://www.mega.com), a Software Company in Paris (France) that provides Modeling Tools for Enterprise Architecture, Enterprise Governance Risk, and Compliance Management. He is an experienced Manager and Senior Solutions Architect with high skills in Software Architecture and Enterprise Architecture.
He loves sharing his knowledge and experience via his blog, by speaking at conferences, writing technical books, writing articles in the technical press, giving software courses as MCT, and coaching co-workers in his company. He frequently collaborates with Microsoft, and you can find him quite often at the Microsoft Technology Center (MTC) in Paris.
Microsoft awarded him in 2011 with the Microsoft® Most Valuable Professional (MVP C#) Award for his numerous contributions to the Microsoft community. Microsoft seeks to recognize the best and brightest from technology communities around the world with the MVP Award. These exceptional and highly-respected individuals come from more than 90 countries, serve their local online and offline communities, and have an impact worldwide. Jason is very proud to be one of them.
Please feel free to contact him via his blog if you need any technical assistance or want to discuss technical subjects (http://www.jasondeoliveira.com).
Jason has worked on the following books:
I would like to thank my lovely wife, Orianne, and my beautiful daughters, Julia and Léonie, for supporting me in my work and for accepting long days and short nights during the week and sometimes even during the weekend. My life would not be the same without them!
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.
https://www2.packtpub.com/books/subscription/packtlib
Do you need instant solutions to your IT questions? PacktLib is Packt's online digital book library. Here, you can search, access, and read Packt's entire library of books.
Microsoft has released a new open source and cross-platform web application framework, called ASP.NET Core. It runs on top of .NET Core, which is also open source, and is primarily used with the C# programming language. You are no longer tied to using Windows with ASP.NET, and you can now develop on a Mac and deploy to Linux. This new platform also offers much higher performance.
In today's world, a web application that only performs well on a developer's workstation and fails to deliver high-performance in production, is unacceptable. The way that web applications are now deployed at scale has changed, and development practices must adapt to take advantage of this. By reading this book, you'll learn about the modern way of making high-performance web applications, and how to do this with ASP.NET Core.
This book addresses web application performance-improvement techniques from both a general standpoint (HTTP, HTTPS, HTTP/2, TCP/IP, database access, compression, I/O, asset optimization, caching, message queuing, and other concerns) and from a C#, ASP.NET Core, and .NET Core perspective. This includes delving into the details of the latest frameworks and demonstrating software design patterns that improve performance.
We will highlight common performance pitfalls, which can often occur unnoticed on developer workstations, along with strategies to detect and resolve these issues early. By understanding and addressing challenges upfront, you can avoid nasty surprises when it comes to deployment time.
We will introduce performance improvements along with the trade-offs that they entail. We will strike a balance between premature optimization and inefficient code by taking a scientific and evidence-based approach, focusing on the big problems and avoiding changes that have little impact.
We assume that you understand the importance of performance for web applications, but we will recap why it's crucial. However, you may not have had any specific or actionable advice, or have much experience of performance problems occurring in the wild.
By reading this book, you'll understand what problems can occur when web applications are deployed at scale to distributed infrastructure, and know how to avoid or mitigate these issues. You will gain experience of how to write high-performance applications without having to learn about issues the hard way, possibly late at night.
You'll see what's new in ASP.NET Core, why it's been rebuilt from the ground up, and what this means for performance. You will understand the future of .NET Core and how you can now develop on and deploy to Windows, Mac OS X, and Linux. You'll appreciate the performance of new features in ASP.NET Core, including updates to the Razor view engine, and you will be aware of cross platform tools, such as Visual Studio Code.
Let's take a look at what topics we'll be covering throughout the book.
Chapter 1, Why Performance Is a Feature, discusses the basic premise of this book and shows you why you need to care about the performance of your software. Responsive applications are vital, and it's not simply enough to have functionality work, it also needs to be quick.
Think of the last time you heard someone complaining about an app or website, and it's likely they were unhappy with the performance. Poor performance doesn't only make users unhappy, it also affects your bottom-line. There's good data to suggest that fast performance increases engagement and improves conversion rates, which is why it's rewarded by search engines.
Chapter 2, Measuring Performance Bottlenecks, tells you that the only way you can solve performance problems is to carefully measure your application. Without knowing where a problem lies, your chance of solving it is extremely slim, and you won't even know whether you've improved matters or made things worse.
We will highlight a few ways of manually monitoring performance and some helpful tools that you can use to measure statistics. You'll see how to gain insights into the database, application, HTTP, and network levels of your software so that you know what is going on internally. We'll also show you how to build your own basic timing code and cover the importance of taking a scientific approach to the results.
Chapter 3, Fixing Common Performance Problems, looks at some of the most frequent performance mistakes. We'll show you how to fix simple issues across a range of different application areas, for example, how to optimize media with image resizing or encoding, Select N+1 problems, and asynchronous background operations.
We will also talk a little about using hardware to improve performance once you know where the bottlenecks lie. This approach buys you some time and allows you to fix things properly at a reasonable pace.
Chapter 4, Addressing Network Performance, digs into the networking layer that underpins all web applications. We'll show you how remote resources can slow down your app and demonstrate what you can do about measuring and addressing these problems.
We will look at internet protocols, including TCP/IP, HTTP, HTTP/2, and WebSockets, along with a primer on encryption and how all of these can alter performance. We'll cover compression of textual and image-based assets, including some exotic image formats. Finally, we will introduce caching at the browser, server, proxy, and Content Delivery Network (CDN) levels, showing you some of the basics.
Chapter 5, Optimizing I/O Performance, focuses on input/output and how this can negatively affect performance. We will look at disks, databases, and remote APIs, many of which use the network, particularly if virtualized. We'll cover batching your requests and optimizing database usage with aggregates or sampling, aiming to reduce the data and time required.
Due to networking's ubiquity in cloud environments, we'll spend considerable time on network diagnostics, including pinging, route tracing, and looking up records in the domain name system. You'll learn how latency can be driven by physical distance, or geography, and how this can cause problems for your application. We'll also demonstrate how to build your own networking information gathering tools using .NET.
Chapter 6, Understanding Code Execution and Asynchronous Operations, jumps into the intricacies of C# code and looks at how its execution can alter performance. We'll look at the various open source projects that make up ASP.NET Core and .NET Core, including Kestrel—a high-performance web server.
We will examine the importance of choosing the correct data structures and look at various examples of different options, such as lists and dictionaries. We'll also look at hashing, serialization, and perform some simple benchmarking.
You will learn some techniques that can speed up your processing by parallelizing it, such as Single Instruction Multiple Data (SIMD) and parallel extensions programming with the Task Parallel Library (TPL) and Parallel LINQ (PLINQ). You'll also see some practices that are best avoided, due to their performance penalties, such as reflection and regular expressions.
Chapter 7, Learning Caching and Message Queuing, initially looks at caching, which is widely regarded as difficult. You'll see how caching works from a HTTP perspective in browsers, web servers, proxies, and CDNs. You will learn about cache busting (or breaking) to force your changes and using the new JavaScript service workers in modern browsers to gain finer control over caching.
Additionally, we'll examine caching at the application and database levels in your infrastructure. We will see the benefits of in-memory caches, such as Redis, and how these can reduce the load on your database, lower latency, and increase the performance of your application.
We will investigate message queuing as a way to build a distributed and reliable system. We'll use analogies to explain how asynchronous message passing systems work and show you some common styles of message queuing, including unicast and pub/sub.
We will also show you how message queuing can be useful to an internal caching layer by broadcasting cache invalidation data. You'll learn about message brokers, such as RabbitMQ, and various libraries to interact with them from .NET.
Chapter 8, The Downsides of Performance-Enhancing Tools, concentrates on the negatives of the techniques that we will have covered because nothing comes for free. We'll discuss the virtues of various methods to reduce complexity, use frameworks, and design distributed architecture. We will also cover project culture and see how high-performance is not simply about code but about people too.
We'll look into possible solutions to tackle the problem of distributed debugging and see some available technologies to centrally manage application logging. We'll have a brief introduction to statistics so that you can make sense of your performance metrics, and we will touch upon managing caches.
Chapter 9, Monitoring Performance Regressions, again takes a look at at measuring performance, but in this case, from an automation and Continuous Integration (CI) perspective. We'll reiterate the importance of monitoring and show how you can build this into your development workflow to make it routine and almost transparent. You will see how it is possible to automate almost any type of testing, from simple unit testing to integration testing, and even complex browser User Interface (UI) testing.
We'll show you how you can make your tests more realistic and useful using techniques, such as blue-green deployment and feature switching. You will discover how to perform A/B testing of two versions of a webpage with some very basic feature switching and a few options for fun hardware to keep people engaged in test results. We'll also cover DevOps practices and cloud hosting, both of which make CI easier to implement and complement it nicely.
Chapter 10, The Way Ahead, briefly sums up the lessons of the book and then has a look at some advanced topics that you may like to read more about. We will also try to predict the future for the .NET Core platforms and give you some ideas to take further.
You will need a development environment to follow the code examples in this book, either Visual Studio Community 2015 or Visual Studio Code if you're not on Windows. You can also use your text editor of choice and the dotnet command line tool. If you use Visual Studio, then you should also install the .NET Core SDK and tooling and the latest NuGet extension.
For some of the chapters, you will also need SQL Server 2014 Express. You can use 2016 too, particularly if you are on Linux. However, you can also use Azure and run against a cloud database.
There are other tools that we will cover, but we will introduce these as they are used. The detailed software/hardware list is uploaded along with the code files.
This book is mainly aimed at ASP.NET and C# developers, but developers used to other open source platforms may also be interested in .NET Core. You should have experience with the MVC framework for web-application development and be looking to deploy applications that will perform well on live-production environments. These can be virtual machines or hosted by a cloud-service provider, such as AWS or Azure.
Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
You can download the code files by following these steps:
You can also download the code files by clicking on the Code Files button on the book's webpage at the Packt Publishing website. This page can be accessed by entering the book's name in the Search box. Please note that you need to be logged in to your Packt account.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/ASP.NET-Core-1.0-High-Performance We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.
To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.
Please contact us at [email protected] with a link to the suspected pirated material.
We appreciate your help in protecting our authors and our ability to bring you valuable content.
If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.
This is an exciting time to be a C# developer. Microsoft is in the middle of one of the biggest changes in its history, and it is embracing open source software. The ASP.NET and .NET frameworks are being rebuilt from the ground up to be componentized, cross-platform, and open source.
ASP.NET Core 1.0 and .NET Core 1.0 (previously called ASP.NET 5 and .NET Core 5) embrace many ideas from popular open source projects, such as Go's ability to produce a statically-linked, standalone binary. You can now compile a single native executable that is free of any external dependencies and run it on a system without .NET installed.
The ASP.NET Model View Controller (MVC) web application framework, which is now part of ASP.NET Core 1.0, borrows heavily from Ruby on Rails and Microsoft is keen in promoting tools, such as Node.js, Grunt, gulp, and Yeoman. There is also TypeScript, which is a statically-typed version of JavaScript that was developed at Microsoft.
By reading this book, you will learn how to write high-performance software using these new .NET Core technologies. You'll be able to make your web applications responsive to input and scalable to demand.
We'll focus on the latest Core versions of .NET. Yet, many of these techniques also apply to previous versions, and they will be useful for web application development in general (in any language or framework).
Understanding how all of these new frameworks and libraries fit together can be a bit confusing. We'll present the various available options while still using the newest technology, guiding you down the path to high-speed success, and avoiding performance pitfalls.
After finishing this book, you will understand what problems can occur when web applications are deployed at scale (to distributed infrastructure) and know how to avoid or mitigate these issues. You will gain the experience of how to write high-performance applications without learning about issues the hard way.
In this chapter, we will cover the following topics.
You may have previously heard about the practice of treating performance as a first-class feature. Traditionally, performance (along with things such as security, availability and uptime) was only considered a Non-Functional Requirement (NFR) and usually had some arbitrary made-up metrics that needed to be fulfilled. You may have heard the term "performant" before. This is the quality of performing well and, often, is captured in requirements without quantification, providing very little value. It is better to avoid this sort of corporate jargon when corresponding with clients or users.
Using the outdated waterfall method of development, these NFRs were inevitably left until the end, and dropped from an over-budget and late project in order to get the functional requirements completed. This resulted in a substandard product that was unreliable, slow, and often insecure (as reliability and security are also often neglected NFRs). Think about how many times you're frustrated at software that lags behind in responding to your input. Perhaps, you used a ticket-vending machine or a self-service checkout that is unresponsive to the point of being unusable.
There is a better way. By treating performance as a feature and considering it at every stage of your agile development process, you can get users and customers to love your product. When software responds quicker than a user can perceive, it is a delight to use, and this doesn't slow them down. When there is noticeable lag, then users need to adjust their behavior to wait for the machine instead of working at their own pace.
Computers have incredible amounts of processing power today, and they now possess many more resources than they did even just a few years ago. So, why do we still have software that is noticeably slow at responding, when computers are so fast and can calculate much quicker than people can? The answer to this is poorly written software that does not consider performance. Why does this happen? The reason is that often the signs of poor performance are not visible in development, and they only appear when deployed. However, if you know what to look for, then you can avoid these problems before releasing your software to the production environment.
This book will show you how to write software that is a joy to use and never keeps the user waiting or uninformed. You will learn how to make products that users will love instead of products that frustrate them all the time.
Let's take a look at some common areas of performance problems and see whether they matter or not. We will also learn why we often miss these issues during development.
People often focus on the speed of the programming language that is used. However, this often misses the point. This is a very simplistic view that glosses over the nuances of technology choices. It is easy to write slow software in any language.
With the huge amounts of processing speed that is available today, relatively "slow" interpreted languages can often be fast enough, and the increase in development speed is worth it. It is important to understand the arguments and the trade-offs involved even if by reading this book you have already decided to use C# and .NET.
The way to write the fastest software is to get down to the metal and write in assembler (or even machine code). This is extremely time consuming, requires expert knowledge, and ties you to a particular processor architecture and instruction set; therefore, we rarely do this these days. If this happens, then it's only done for very niche applications (such as virtual reality games, scientific data crunching, and sometimes embedded devices) and usually only for a tiny part of the software.
The next level of abstraction up is writing in a language, such as Go, C, or C++, and compiling the code to run on the machine. This is still popular for games and other performance-sensitive applications, but you often have to manage your own memory (which can cause memory leaks or security issues, such as buffer overflows).
A level above is software that compiles to an intermediate language or byte code and runs on a virtual machine. Examples of this are Java, Scala, Clojure, and, of course, C#. Memory management is normally taken care of, and there is usually a Garbage Collector (GC) to tidy up unused references (Go also has a GC). These applications can run on multiple platforms, and they are safer. However, you can still get near to native performance in terms of execution speed.
Above these are interpreted languages, such as Ruby, Python, and JavaScript. These languages are not usually compiled, and they are run line-by-line by an interpreter. They usually run slower than a compiled language, but this is often not a problem. A more serious concern is catching bugs when using dynamic typing. You won't be able to see an error until you encounter it, whereas many errors can be caught at compile time when using statically-typed languages.
It is best to avoid generic advice. You may hear an argument against using Ruby on Rails, citing the example of Twitter having to migrate to Java for performance reasons. This may well not be a problem for your application, and indeed having the popularity of Twitter would be a nice problem to have. A bigger concern when running Rails may be the large memory footprint, making it expensive to run on cloud instances.
This section is only to give you a taste, and the main lesson is that normally, language doesn't matter. It is not usually the language that makes a program slow, it's poor design choices. C# offers a nice balance between speed and flexibility that makes it suitable for a wide range of applications, especially server-side web applications.
There are many types of performance problems, and most of them are independent of the programming language that is used. A lot of these result from how the code runs on the computer, and we will cover the impact of this later on in the chapter.
We will briefly introduce common performance problems here and will cover them in more detail in later chapters of this book. Issues that you may encounter will usually fall into a few simple categories, including the following:
When writing software for a platform, you are usually constrained by two resources. These are the computation processing speed and accessing remote (to the processor) resources.
Processing speed is rarely a limiting factor these days, and this could be traded for other resources, for example, compressing some data to reduce the network transfer time.
Accessing remote resources, such as main memory, disk, and the network will have various time costs. It is important to understand that speed is not a single value, and it has multiple parameters. The most important of these are bandwidth and, crucially, latency.
Latency is the lag in time before the operation starts, whereas bandwidth is the rate at which data is transferred once the operation starts. Posting a hard drive has a very high bandwidth, but it also has very high latency. This would make it very slow to send lots of text files back and forth, but perhaps, this is a good choice to send a large batch of 3D videos (depending on the Weissman score). A mobile phone data connection may be better for the text files.
Although this is a contrived example, the same concerns are applicable to every layer of the computing stack often with similar orders of magnitude in time difference. The problem is that the differences are too quick to perceive, and we need to use tools and science to see them.
The secret to solving performance problems is in gaining a deeper understanding of the technology and knowing what happens at the lower levels. You should appreciate what the framework is doing with your instructions at the network level. It's also important to have a basic grasp of how these commands run on the underlying hardware, and how they are affected by the infrastructure that they are deployed to.
Performance is not always important in every situation. Learning when performance does and doesn't matter is an important skill to acquire. A general rule of thumb is that if the user has to wait for something to happen, then it should perform well. If this is something that can be performed asynchronously, then the constraints are not as strict, unless an operation is so slow that it takes longer than the time window for it; for example, an overnight batch job on an old financial services mainframe.
A good example from a web application standpoint is rendering user view versus sending e-mail. It is a common, yet naïve, practice to accept a form submission and send an e-mail (or worse, many e-mails) before returning the result. Yet, unlike a database update, an e-mail is not something that happens almost instantly. There are many stages over which we have no control that will delay an e-mail in reaching a user. Therefore, there is no need to send an e-mail before returning the result of the form. You can do this offline and asynchronously after the result of the form submission is returned.
The important thing to remember here is that it is the perception of performance that matters and not absolute performance. It can be better to not do some work (or at least defer it) rather than speed it up.
This may be counterintuitive, especially considering how individual computer operations can be too quick to perceive. However, the multiplying factor is scale. One operation may be relatively quick, but millions of them may accumulate to a visible delay. Optimizing these will have a corresponding effect due to the magnification. Improving code that runs in a tight loop or for every user is better than fixing a routine that runs only once a day.
In some situations, processes are designed to be slow, and this is essential to their operation and security. A good example of this, which may be hit in profiling, is password hashing or key stretching. A secure password hashing function should be slow so that the password, which (despite being bad practice) may have been reused on other services, is not easily recovered.
We should not use generic hashing functions, such as MD5, SHA1, and SHA256, to hash passwords because they are too quick. Some better algorithms that are designed for this task are PBKDF2 and bcrypt, or even Argon2 for new projects. Always remember to use a unique salt per password too. We won't go into any more details here, but you can clearly see that speeding up password hashing would be bad, and it's important to identify where to apply optimizations.
One of the main reasons that performance issues are not noticed in development is that some problems are not perceivable on a development system. Issues may not occur until latency increases. This may be because a large amount of data was loaded into the system and retrieving a specific record takes longer. This may also be because each piece of the system is deployed to a separate server, increasing the network latency. When the number of users accessing a resource increases, then the latency will also increase.
For example, we can quickly insert a row into an empty database or retrieve a record from a small table, especially when the database is running on the same physical machine as the web server. When a web server is on one virtual machine and the big database server is on another, then the time taken for this operation can increase dramatically.
This will not be a problem for one single database operation, which appears just as quick to a user in both cases. However, if the software is poorly written and performs hundreds or even thousands of database operations per request, then this quickly becomes slow.
Scale this up to all the users that a web server deals with (and all of the web servers) and this can be a real problem. A developer may not notice that this problem exists if they're not looking for it, as the software performs well on their workstation. Tools can help in identifying these problems before the software is released.
The most important takeaway from this book is the importance of measuring. You need to measure problems or you can't fix them. You won't even know when you have fixed them. Measurement is the key to fixing performance issues before they become noticeable. Slow operations can be identified early on, and then they can be fixed.
However, not all operations need optimizing. It's important to keep a sense of perspective, but you should understand where the chokepoints are and how they will behave when magnified by scale. We'll cover measuring and profiling in the next chapter.
