Дата публикации статьи: 08.07.2003 00:00

Оптимизация размера приложений

Многие наверное сталкивались с проблемой того, что ваши приложения не помещаются на дискете, а этого очень хочется, или же они настолько большие, что распространять их через Интернет достаточно трудно, поэтому необходимо хоть как-то уменьшить размер приложений.
Сначала посмотрите на свое приложение со стороны. Если вы используете одну и ту же картинку или иконку на нескольких формах, то не лучше ли использовать ресурсы? Причем я рекомендую помещать ресурсы вне приложения, например в отдельную DLL. Конечно возникнут некоторые трудности при разработке с размещением контролов на форму, но эту проблему легко решить: вы присваиваете Image1 картинку и создаете свой "неповторимый дизайн", после чего помещаете курсов на раздел свойств Picture и нажимаете Delete на клавиатуре. Картинка благополучно исчезает. А при загрузке форму достаете картинку из ресурсов, которые лежат в библиотеке.
Создание библиотеки ресурсов

Создаете проект ActiveX DLL - ResourceLib, запускаете Resource Editor из Add-Ins, создаете файл ресурсов, присваиваете ресурсам идентификаторы. теперь переименовываете Class 1 в MainResources и в классе создаете такую функцию:

Public Function SetPicture(PicName As String) As Object
Set SetPicture = LoadResPicture(PicName0)
End Function

Для использования библиотеки нужно добавить ее к проекту в Project => References и в Form_Load загнать загрузку картинок:

Dim ResLib As New ResourceLib.MainResourcer
Image1.Picture = resLib.SetPicture("101")


Еще один полезный прием - когда вы закончили создание приложения, библиотеки, контрола и т.д. и т.п. Перед компиляцией проекта закройте VB IDE и потом уже откройте и откомпилируйте проект, т.к. VB иногда оставляет описания неиспользуемых и уже удаленных разработчиком функций и переменных, что существенно увеличивает размер приложений.

Оптимизация потребления ресурсов системы

Думаю, что это не будет новостью, что в мире еще много пользователей таких машин, как 486dx и даже 386dx. А если приложение бездумно расходует ресурсы системы, то пользователь скорее выкинет его подальше, чем продолжит использовать и уж тем более не захочет его покупать.
Для снижения потребления ресурсов первым делом откажитесь от использования переменных типа Variant там, где это только возможно. Если вы работаете с числами, то используйте на Double, а Single - они меньше занимают памяти системы.
Опасайтесь таких объявлений, как:

Dim a, b, c, d, e As Integer
На самом деле Integer только e, а a, b, c, d - имеют тип Variant.


Создавайте как можно меньше переменных. Например, если одна переменная может быть использована вместо еще одной - делайте это. При работе с объектными переменными сразу устанавливайте их значение в Nothing, как только они больше не нужны:

Set MyObjVar = Nothing

При единичных вызовах функций из библиотек, не допускайте использования такого кода в:

Private Sub Form_Load()
Dim ml As MyLib
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set ml = Nothing
End Sub

Вместо этого лучше объявлять переменную при вызове:

Private Sub Command1_Click()
Dim ml As New MyLib
'Действия
Set ml = Nothing
End Sub

Там, где можно обходиться стандартными контролами, не используйте никакие другие. А также, если вам нужно текстовое поле, только для чтения - создайте Label с BorderStyle = 1. Вместо PictureBox используйте Image.
после выгрузки формы очищайте всю занимаемую ей память:

Unload frmMain
Set frmMain = Nothing

К сожалению в VB механизм "сборки мусора" достаточно убог, поэтому там, где это возможно программисту нужно самому освобождать неиспользуемые переменные и следить за использованием ресурсов.

Оптимизация скорости исполнения

Везде используйте Option Explicit, это разрешит не отслеживать типы переменных, придерживаясь указанных, что ускоряет работу с переменными. Учтите, что Private переменные формы гораздо быстрее Public переменных модуля и Static переменных той же формы. Для преобразования типов данных используйте CInt, CLng, CStr.
Чаще используйте операторы And, Or, Xor вместо длинных проверок If ... Then ... ElseIf ... Then ... End If, которые сами по себе достаточно медлительны.
Если вы создаете библиотеку ActiveX DLL, которой для работы нужны достаточные ресурсы системы, то включите в нее стандартный модуль, содержащий Sub Main() и укажите ее как стартовую в свойствах проекта. Тогда управление будет передано этой процедуре при каждой инициализации библиотеки. В main вы можете проверять ресурсы системы и включать тот или иной режим работы в зависимости от результата.
При работе со строками избегайте частого использования оператора & - помните, что конкатенация довольно медленная операция. Для замены символов в строке пользуйтесь функцией Replace, которая встроена в VB6.0, она работает гораздо быстрее циклической проверки и замены с помощью InStr и Mid. В операторах сравнения использование ASCII кода гораздо быстрее, чем использование символов.
Использование встроенных VB функций и встроенных VB констант, заметно ускоряет работу. Например при выводе сообщений вместо: MsgBox "Message", 64, "Title" лучше написать так: MsgBox "Message", vbCritical + vbOKOnly, "Title".
Избегайте лишних операций в своем коде, например:

If LCase($Text1.Text) = LCase($Text2.Text) Then ...

Нужно заменить на:

If StrComp(Text1.Text, Text2.Text , vbTextCompare) = 0 Then ...

Это увеличит скорость выполнения, т.к. на придется приводить строки к одинаковому регистру, т.е. выполнять лишние операции.
Полезно помещать наиболее медленные процедуры в Form_Activate, вместо Form_Load. Если вашему приложению для работы необходимо сохранять и читать данные из файлов - создавайте обычные текстовые файлы, вместо Binary и Random используйте input и Output. А если вам необходимо сохранять настройки - воспользуйтесь реестом Windows, или INI файлом. Для работы с INI есть такие функции:

Declare Function GetPrivateProfileString Lib "Kernel32" Alias "GetPrivateProfileStringA" (ByVal Section As String, ByVal Key As String, ByVal Default As String, ByVal GetStr As String, ByVal nSize As Long, ByVal INIfile As String) As Long
Declare Function WritePrivateProfileString Lib "Kernel32" Alias "WritePrivateProfileStringA" (ByVal Section As String, ByVal Key As String, ByVal putStr As String, ByVal INIfile As String) As Long
Public Function GetSettingIni(File As String, Section As String, Key As String,
Optional dStr As Variant) As Variant
Dim GetStr As String, ret As Integer, dS As String
GetStr = String$(255, 0)
dS = CStr(dStr)
ret = GetPrivateProfileString(Section, Key, "", GetStr, Len(GetStr), File)
If ret = 0 Then
GetSettingIni = dStr
Else
GetSettingIni = CVar(Left(GetStr, InStr(GetStr, Chr(0)) - 1))
End If
End Function
Public Sub SaveSettingIni(File As String, Section As String, Key As String, wStr As Variant)
Dim ret As Integer, wS As String
wS = CStr(wStr)
ret = WritePrivateProfileString(Section, Key, wStr, File)
End Sub

Если вам надо сохранять большое количество данных возникает проблема выбора - что лучше: быстрая база данных, которая занимает много места и требует времени на создания кода для работы с ней, или же использовать текстовый файл, что не конструктивно если объем данных очень велик. Что использовать надо решать в каждой конкретной ситуации.

Если нужно сохранить некоторое значение на недолгий срок, просто и быстро использовать буфер обмена Windows. Но при этом возникает опасность потери данных, если пользователь захочет очистить буфер или скопировать в него еще что-то, что вероятнее. Но это очень быстрый способ, поэтому решать вам ...