Оптимизиране на VBA макроси

Бележки от първо лице за ИТ, новини и технологично остаряване.

Блог -> VBA макро оптимизация. Част 2

И така, след принудителна пауза, най-накрая съм готов да се върна към темата за VBA макро оптимизацията, която започнах в блога и оставих много интересни неща извън обхвата на първата част на статията. Днес ще говорим за оптимизиране на кода за скорост и размер на изпълнение на ниско и средно ниво. Ако си готов, значи и аз съм готов. Отивам?

Правилният избор на един или друг оператор обикновено не дава голяма печалба в производителността, така че не трябва да пренаписвате всички програми, които създавате от нулата. Освен това, добре оптимизиран код често е по-трудно да се разбере и поддържа - което има значение, ако работите в група или пишете примерни програми за обучение. Затова просто опитайте тези съвети във вашите бъдещи програми. Може да искате да промените обичайния си стил на програмиране и да ги използвате постоянно.

Сега да преминем към цикли, условия и процедури. Първо ще ви дам няколко стандартни съвета, които се отнасят до всеки език за програмиране.

1. Потърсете повтарящ се код и го извлечете в процедури. Разпределете дублиращи се редове до константи.
2. Ако цикълът е кратък и се изпълнява 2-3 пъти, разширете го (просто напишете тялото тези 2-3 пъти). Разгънете малки подпрограми и подпрограми, които се извикват веднъж, тоест тези, които служат само за абстрахиране от същността на извършените действия. Извадете всичко от цикли, като преброите междинни стойности на променливи извън цикъла.
3. Комбинирайте For Loops със същия брой повторения.
4. Избягвайте дълбока рекурсия. Рекурсията претоварва стека и извикванията на процедури са по-бавни от цикъл.
5. Избягвайте ненужната рекурсия, при която една и съща стойност се оценява многократно, създавайки нарастващо дърво от рекурсивни повиквания. Класически пример: рекурсивно изчисляване на числата на Фибоначи, когато процедура се извиква два пъти, за да изчисли предишните членове на поредица, извиканите процедури от своя страна правят две рекурсивни повиквания и т.н. Това изчислява същите стойности, но те не се записват.

И сега - ще изброя препоръките, които се отнасят само за VBA. Както всеки друг език за програмиране, VBA има своя собствена „жар“ и тези функции си струва да се обърнат внимание, ако искате да напишете ефективен код.

1. Не прекалявайте с функциите Избор, Ако и Превключване, като ги замествате с If и Select Case, особено в повтарящи се цикли. Защо? Те са много по-бавни от обикновените If и Case (около 2-3 пъти), въпреки че често са по-удобни в някои случаи. Освен това, когато влагате тези функции, производителността значително намалява, тъй като всички стойности ще бъдат изчислени, за да бъдат предадени на функцията, а не само тези, които са необходими.
2. Разбийте условието And на две вложени условия. Освен това външното условие не трябва да се изпълнява по-често от вътрешното и/или да бъде много по-просто от него. Ако външното състояние е неправилно, програмата няма да провери вътрешното, а ще премине направо към следващия раздел на програмата:

- Това е толкова лошо
Ако х И у тогава
s = s & "
Край ако

- И така - добре
Ако x тогава
Ако y Тогава s = s & "
Край ако

Компилаторът VBA не извършва такива оптимизации автоматично, както например правят Delphi, VC ++ и редица Basic компилатори.

Също така, изберете стойностите на флага рационално. Преходът е малко по-бърз, когато условието If. Тогава. Else е false, not true, което най-вероятно се дължи на вътрешните особености на изпълнението на p-code. Опитайте се да проектирате често проверявани условия, така че "false", а не "true" клонът да се изпълнява по-често (това се отнася главно до избора на стойности на флага). Например следните два макроса са почти еднакви, но първият се изпълнява с 18 секунди по-бързо от втория: