Как оптимизировать программу на С#?
Вообще не думайте над этим. От слова совсем. 

Я вот знаю что надо использовать Массив, а не Лист там, где это можно.

То есть вы намеренно усложняете себе жизнь и используете более тормознутое решение, потому что кто то вам сказал.

Общие правила такие: 
* Не оптимизируй
* Пиши что бы было понятно
* Испортить успеешь всегда
* Ты всегда ошибешься
* Точно скажет только профайлер!!!

Вот  вам пример уже допиленного для перрфоманса кода.

https://github.com/vkorotenko/FiasServer/blob/mast...

Посмотрите как используются вот эти переменные
private List<NormativeDocument> _normDocs;
private HashSet<Guid> _normDocIds;
Использовать профайлер: он показывает, сколько времени и сколько раз выполняется каждый кусок кода, каждая функция, каждый сеттер + сколько оперативной памяти занимает+нагрузку на cpu, gpu, сеть + много чего ещё.
Вот пример: https://www.jetbrains.com/profiler/ , https://www.jetbrains.com/dotmemory/

Статьи
-Оптимизация производительности .NET (C#) приложений (конкретные советы с некоторым пояснением): https://habr.com/ru/post/466931/

-Как найти узкие места в приложении (профайлер): https://xakep.ru/2011/03/22/55102/

-Ну и Wiki Профилирование

Книги
Что касаемо умения правильно мыслить в таких вещах, то рекомендую классику:
"Искусство программирования" ("Art of programming") Д. Э. Кнута, 
"Хакинг. Искусство эксплойта" ("Hacking: The Art of Exploitation") Джона Эриксона

И вообще читайте и решайте математику хотя бы часик-два в неделю