09/14/2023
By Mike Rousos
This article provides guidelines for maximizing performance and reliability of ASP.NET Core apps.
09/14/2023
By Mike Rousos
This article provides guidelines for maximizing performance and reliability of ASP.NET Core apps.
Key 1. Fundamental Theorem of Readability.
Code should be written to minimize the time it would take for someone else to understand it (Time-Till-Understanding metric).
Key 2. Packing Information into Names. Pack information into your names:
Key 3. Actively scrutinize your names by asking yourself, 'What other meanings could someone interpret from this name?'
Before you decide on a name, play devil's advocate and imagine how your name might be misunderstood. The best names are resistant to misinterpretation.
Key 4. Aestetics vs Design: Consistent style is more important than the 'right' style.
Key 5. The purpose of commenting is to help the reader know as much as the writer did.
What not to comment:
Thoughts you should be recording include:
Put yourself in the reader’s shoes:
Key 6. Making Comments Precise and Compact: Comments should have a high information-to-space ratio
Key 7. Making Control Flow Easy to Read: Make all your conditionals, loops, and other changes to control flow as 'natural' as possible-written in a way that doesn't make the reader stop and reread your code.
Key 8. Break down your giant expressions into more digestible pieces.
a. introduce 'explaining variables' that capture the value of some large subexpression. This approach has three benefits: breaks down a giant expression into pieces; documents the code by describing subexpression with a succinct name; helps the reader identify the main 'concepts' in the code.
b. manipulate your logic using De Morgan's laws—this technique can sometimes rewrite a boolean expression in a cleaner way (e.g., if (!(a && !b)) turns into if (!a || b)).
Key 9. How the variables in a program can quickly accumulate and become too much to keep track of. You can make your code easier to read by having fewer variables and making them as 'lightweight' as possible:
a. Eliminate variables that just get in the way.
b. Reduce the scope of each variable to be as small as possible.
c. Prefer write-once variables. Variables that are set only once (or const, final, or otherwise immutable) make code easier to understand.
Key 10. Extracting Unrelated Subproblems: separate the generic code from the project-specific code.
As it turns out, most code is generic. By building a large set of libraries and helper functions to solve the general problems, what’s left will be a small core of what makes your program unique.
Key 11. One Task at a Time:
Code should be organized so that it's doing only one task at a time (defragmenting).
Key 12. Turning Thoughts into Code
Key 13. Writing Less Code: most readable code is no code at all
[ Adventure, excitement-a Jedi craves not these things. ^ Yoda ]
Each new line of code needs to be tested, documented, and maintained. Further, the more code in your codebase, the 'heavier' it gets and the harder it is to develop in.
Avoid writing new lines of code by:
Key 14. Testing and Readability: Test code should be readable so that other coders are comfortable changing or adding tests.
Appendix: Designing and Implementing
a. First, start by coding a naive solution. This helped us realize two design challenges: speed and memory use.
b. Next, try a 'conveyor belt' design. This design improved the speed and memory use but still wasn’t good enough for high-performance applications.
c. Our final design solved the previous problems by breaking things down into subproblems.
@tveastman: I have a Python program I run every day, it takes 1.5 seconds. I spent six hours re-writing it in rust, now it takes 0.06 seconds. That efficiency improvement means I’ll make my time back in 41 years, 24 days :-)You’ve probably heard this mantra: “programmer time is more expensive than computer time”. What it means basically is that we’re wasting computers at an unprecedented scale. Would you buy a car if it eats 100 liters per 100 kilometers? How about 1000 liters? With computers, we do that all the time.
public static class ObsoleteExample
{
// Mark OrderDetailTotal As Obsolete.
[ObsoleteAttribute("This property (DepricatedOrderDetailTotal) is obsolete. Use InvoiceTotal instead.", false)]
public static decimal OrderDetailTotal
{
get
{
return 12m;
}
}
public static decimal InvoiceTotal
{
get
{
return 25m;
}
}
// Mark CalculateOrderDetailTotal As Obsolete.
[ObsoleteAttribute("This method is obsolete. Call CalculateInvoiceTotal instead.", true)]
public static decimal CalculateOrderDetailTotal()
{
return 0m;
}
public static decimal CalculateInvoiceTotal()
{
return 1m;
}
}
Основные
|
Делегирования •
Функционального дизайна •
Неизменяемый объект •
Интерфейс
|
Порождающие
|
Абстрактная фабрика •
Строитель •
Фабричный метод •
Прототип •
Одиночка •
Отложенная инициализация •
Объектный пул
|
Структурные
|
Адаптер •
Мост •
Компоновщик •
Декоратор •
Фасад •
Заместитель •
Приспособленец •
Выделение частного класса данных
|
Поведения
|
Цепочка обязанностей •
Команда •
Интерпретатор •
Итератор •
Посредник •
Хранитель •
Наблюдатель •
Состояние •
Стратегия •
Шаблонный метод •
Посетитель
|
Параллельного
программирования
|
Блокировка с двойной проверкой •
Планировщик •
Однопоточное выполнение
|
Бен Черри
Код программ таков, что даже если сайт или программа прекрасно работают и отлично выглядят, то за кулисами всё, что заставляет его работать, состоит из ошибок, ляпов и костылей. Он работает едва-едва и иногда вообще непонятно, почему.
Брайан Хьюмс
Занимает это на деле больше или меньше процентов времени, но каждый раз нам действительно необходимо подумать – а что пользователь может тут сломать. Куда нажмёт, что введёт, и как можно понять то, что мы пытаемся сделать, неправильно. Если бы мы рассчитывали только на себя, у программ было бы слишком много проблем – ведь мы знаем, как программа работает, а пользователь не знает.