Статьи

Страница 2 из 3.   [1] [2] [3]

88 советов по оптимизации программ на Visual Basic


РАЗБЕРИТЕСЬ СО СВОИМИ СТРОКОВЫМИ ОПЕРАЦИЯМИ.

23. Конкатенация - это медленная операция. Если вы хотите заменить 1-2 символа в строке - используйте функцию Mid$:

Mid$(a$, 1, 1) = "A"

Hе используйте такой код:

a$ = "A" & Mid$(a$, 2) 

24. Строковые переменные фиксированной длины часто медленнее, чем стандартные строковые переменные. Фактически, все строковые функции работают только со строками переменной длины. Следовательно, все строки фиксированной длины сначала должны быть преобразованы, прежде, чем обработаются. Это может замедлить ваш код раза в три или четыре.

25. Держитесь подальше от функций без значка "$" таких как Left и Trim, т.к. они возвращают значение типа Variant. Обычные функции Left$ и Trim$ возвращают результат немедленно, без его неявного преобразования в Variant.

26. Использование ASCII кода при сравнении намного быстрее использования самого символа. Например:

' Сравнение с пробелом.
If Left$(a$, 1) = " " Then ... 
' Сравнение через код (на 40% быстрее)
If Asc(a$) = 32 Then ...

Такой подход обычно используют в блоках Select Case

27. Используйте встроенные строковые константы вместо Chr$ (). Например, используйте vbTab вместо Chr$ (9), и vbCrLf вместо Chr$ (13) и Chr$ (10).

28. Использование функции Len, чтобы проверить, содержит ли строка символы- приблизительно на 25 процентов быстрее чем явное сравнение с пустой строкой:

If Len(a$) = 0 Then ...

29. Часто VB программисты сравнивают строки , используя LCASE$ или UCASE$, чтобы преобразовать обе строки перед сравнением. Однако, быстрее прибегнуть к редко используемой функции StrComp:

If StrComp(a$, b$, vbTextCompare) = 0 Then 
'строки равны 
End If

30. Точно также, когда Вам нужно найти подстроку без учета регистра, используйте четвертый параметр функции InStr:

If InStr(1, a$, "vb", vbTextCompare) Then ...

Заметим, что при такой форме синтаксиса, Вы не можете опустить первый аргумент. Если Ваша программа применяет поиск и сравнение исключительно без учета регистра, можете добавить директиву "Option Compare Text" в первую строку каждого модуля.

31. Функция InStr позволяет Вам быстро проверить содержится ли одиночный символ в списке символов. Hапример, так Вы можете определять, содержит ли a$ гласную:

isVowel = InStr("aeiou", a$)

32. Когда Вам надо обработать каждый символ в строке, поместите строку в массив байтов и оперируйте с элементами массива. Помните, что каждый символ Unicode описывается двумя байтами. Такой подход обычно быстрее, т.к. он не использует обычную в таких случаях функцию Mid$ и не нужно создавать временные строки. Например, самый быстрый способ подсчитать кол-во пробелов в строке:

Dim b() as Byte, count As Integer 
b() = source$ 
For i = 1 to UBound(b) Step LenB("A") 
If b(i) = 32 Then count = count + 1 
Next

Отметим нестандартное использование функции LenB(). Она возвращает 2 под VB4/32 и VB5, и 1 под VB4/16, поэтому Вы можете использовать этот фрагмент кода без директивы #If условной компиляции. Будьте внимательны: эта техника может не прокатить, если Вы локализуете свой код для стран, использующих полный набор символов Unicode.

33. Почти забытый оператор Like может часто сохранять много циклов процессора, выполняя сложные сравнения строк в одной операции:

' ID должен быть символом, заканчивающимся тремя цифрами
If ID Like "[A-Z]###" Then ... 

БЫСТРАЯ ЗАГРУЗКА ФОРМ:

34. Если позволяет память, не выгружайте часто используемую форму - просто спрячьте ее, в следующий раз она появится мгновенно. Однако при этом событие Form_Load не произойдет, и Вы будете должны проинициализировать все поля вручную.

35. Не выполняйте длительные операции, такие как открытие базы данных или заполнение list box объемным составляющим в обработчике событий Form_Load. Это лучше сделать в обработчике события Activate. Если Ваша форма немодальная, вы можете установить флаг, чтобы форма не инициализировалась каждый раз, когда она будет терять и получать обратно фокус ввода:

Private Sub Form_Activate()
 Static initDone As Boolean 
 If Not initDone Then 
  ' откройте здесь свою базу данных 
  initDone = True 
 End If 
End Sub

36. Вы ускорите загрузку форм и снизите потребляемые ресурсы, если будете применять более простые элементы управления. Например, не пользуйтесь элементом с вводом по маске (masked-edit controls) если Вам достаточно простого text box’а. В некоторых случаях можно использовать label с рамкой вместо read-only text box, набор Image, вместо Toolbar common control, маленький scrollbar вместо spin button, и т.д.

37. Всегда сбрасывайте форму в Nothing после ее выгрузки. Тем самым вы освободите всю память, занимаемую ее переменными и массивами и обеспечит ее правильную инициализацию при последующем ее вызове:

Unload Form1 
Set Form1 = Nothing

СОВЕТЫ ПО ГРАФИКЕ ПРИДАДУТ ПРИЛОЖЕНИЮ НЕМНОГО СКОРОСТИ.

38. Установка AutoRedraw в False обычно удваивает скорость большинства графических методов, а также снижает требуемое кол-во памяти для ее отображения.

39. Если Вам необходимо установить AutoRedraw в True, попробуйте использовать формы с фиксированной рамкой (fixed-border forms). Фактически, когда у формы изменяемые границы, VB занимает непрерывный кусок памяти, величиной с целый экран, даже если окно никогда не максимизируется. Наоборот, когда у формы фиксированные границы, VB занимает память только под установленный размер формы.

40. Если Ваша форма не содержит графики, или создает графические объекты в процессе работы и они не перекрывают существующие элементы управления, установите свойство ClipControls в False для ускорения работы всех графических методов.

41. Вставляете ли Вы изображения в форму при конструировании, или во время ее выполнения из файла ресурсов, - Вы должны использовать сжатые форматы изображения (compressed bitmaps). Помните, что элемент PictureBox может читать RLE и WMF форматы, а в версии VB5 также PCX и JPEG. Если Вы ранее использовали компоненты третьих фирм для работы с этими форматами, Вы можете избавиться от этого изменив и перекомпилировав свой код под VB5 и сохранив старый файл ресурсов.


ТОНКО ИСПОЛЬЗУЙТЕ ЭЛЕМЕНТЫ УПРАВЛЕНИЯ.

42. Используйте метод Move для изменения размеров или перемещения форм. Это быстрее, чем по отдельности изменять свойства Left, Top, Width, и Height.

43. Если Вам надо часто ссылаться на свойство какого-либо элемента (например в цикле), присвойте ссылку на него временной переменной и используйте в цикле ее, а не объект:

tmp = Check1.Value 
For i = 1 To Ubound(arr) 
arr(i) = tmp 
Next 

Эта техника основана на кэшировании свойства

44. Вы можете сделать элемент невидимым, перед тем как менять несколько его свойств, и после снова сделать его видимым. Это предотвратит его повторные перерисовывания и моргание.

45. Под VB3, можно ускорить свой код используя свойства, назначаемые по умолчанию для элементов. Например, для получения значения поля используйте "Text1" вместо "Text1.Text". Это несправедливо для VB4 и VB5, вне зависимости от режима компиляции (p-code или native-code).

46. Элемент PictureBox очень прожорлив, и если Вам не требуются такие его свойства, как поддержка DDE, графические методы, и способность содержать другие объекты - Вы можете повысить производительность своего приложения, заменив его элементом Image.

47. Используйте по возможности метафайлы (WMF) вместо растровых (BMP) в элементе PictureBox. Они требуют меньше ресурсов и обычно перерисовываются быстрее, чем растровые, когда Вы меняете их размеры.


НЕ ПЛЫВИТЕ ПО ТЕЧЕНИЮ: БЫСТРОЕ ВЫПОЛНЕНИЕ КОДА.

48. Никогда не используйте Single, Double, или Variant типы в качестве переменных цикла в циклах For … Next. Вы можете оптимизировать любой, из своих таких циклов используя в качестве переменных типы Integer или Long.

49. В приложениях VB5, компилированных в native код, GoSubs от 5 до 6 раз медленнее, чем вызовы обычных процедур или функций. И наоборот, при компиляции в p-код GoSub быстрее. Это один из примеров, когда правила оптимизации не применимы одновременно для native и p-кода.

50. Разделите ваше выражение If , содержащее несколько условий с операторами And, на два или более блока с оператором If. Этот способ приводит к увеличению скорости, т.к. следующий If не выполняется, если предыдущий дал False. Например, одиночный If содержащий оператор And:

If x > 0 And Tan(x) < 1 Then y = 1
'Вы можете разделить его на два блока:
If x > 0 Then 
If Tan(x) < 1 Then y = 1 
End If

Измененный код потенциально подавляет вызов функции Tan, которая сама по себе достаточно медленная. Эта техника называется схема сокращенной оценки. Большинство компиляторов, включая устаревший VB DOS компилятор автоматически генерируют код, оптимизированный с помощью этого метода. К сожалению «оптимизированный» компилятор VB здесь просто отдыхает. Более подробное описание этой техники я привожу в своей статье «Ускорьте Ваши 32-битные приложения» в журнале VBPJ за февраль 1996.

51. В структурах Select Case и If … ElseIf всегда первыми располагайте наиболее часто встречающиеся условия.

52. Не заполняйте свой код без необходимости директивами DoEvents, особенно циклы критичные к времени выполнения. Если Вы не можете этого избежать, приемлемым решением может быть вызов DoEvents через каждые N проходов цикла, используя подобное выражение:

If (loopNdx Mod 10) = 0 Then DoEvents

В случае если Вам надо отслеживать события клавиатуры, или мыши, вы можете вызывать DoEvents, в случае если эти события находятся в очереди событий. Используйте для этого API функцию GetInputState:

Public Declare Function GetInputState Lib "user32" Alias "GetInputState" () As Long 
' ... 
If GetInputState() Then DoEvents

53. Аргументы Integer и Long в процедурах будут передаваться быстрее, если вы объявите их в списке аргументов с ключевым словом ByVal. Все другие типы данных нужно передавать по ссылке. Никогда не используйте ByVal для передачи строковых аргументов в локальные процедуры в своих программах.

54. Не пользуйтесь функцией IIf в критичных ко времени циклах. Стандартный блок If ... Else ... Endif всегда быстрее.

55. Не пользуйтесь пустыми циклами For … Next для реализации задержки в вашей программе. Используйте API функцию Sleep, которая не загружает процессор и позволяет другим приложениям в многозадачной среде работать:

Public Declare Sub Sleep Lib "kernel32" (ByVal milliseconds As Long) 
' пауза в 5 сек.
Sleep 5000

Заметим, что эта функция работает только под VB4/32 и VB5. Подобной функции в 16-разрядном Window’s API нет.

56. Перед окончательной компиляцией приложения, удалите или закомментируйте все неработающие куски кода, модули которые Ваша программа не вызывает, и которые часто остаются при написании новых версий. Найти неиспользуемые процедуры и функции непростая задача, и для больших проектов я пользуюсь разработками третьих фирм, которые делают это автоматически. Или запускаю Code Profiler -надстройку и смотрю, какие куски никогда не вызываются в процессе тестирования программы.



Страница 2 из 3.   [1] [2] [3]

   
Hosted by uCoz