Оптимизация приложений visual basic
Оптимизация приложений
Целью любой разработки является создание максимально эффективного приложения. Однако часто некоторые параметры приложений могут быть противоречивыми (например, размер приложения и скорость его работы), и требуется подобрать оптимальное решение для их реализации в проекте. Поиск реализации эффективно работающего приложения в условиях противоречий и ограничений и есть оптимизация.
Как правило, целью оптимизации является создание приложения, выполняющего все поставленные перед ним функциональные задачи максимально быстро и при этом с использованием минимального количества ресурсов системы, в частности места на диске и памяти компьютера при загрузке приложения. Перед проведением оптимизации необходимо ясно представлять, какие параметры являются более важными: скорость или ресурсы. Оптимизация приложения, таким образом, это целая стратегия создания эффективного приложения.
Рассмотрим оптимизацию приложения, включающую в себя следующие основные разделы:
- оптимизацию скорости выполнения приложением вычислений и других действии, измеряемых временем; оптимизацию размера приложения; оптимизацию размера графики приложения.
Конечно, это далеко не полный список, но главные направления оптимизации он отражает.
Перед тем как строить стратегию оптимизации, рекомендуется ответить на следующие три вопроса:
- Что оптимизировать? Где оптимизировать? Когда завершить оптимизацию?
Отвечая на первый вопрос, необходимо выделить цели оптимизации. Например, приложение для расчета заработной платы должно работать максимально быстро, при этом можно пожертвовать его размером. Наоборот, создавая приложение для Internet, необходимо помнить, что проект большого размера не будет работать в сети Internet, т. к. исполняемый файл приложения размером 1 Мбайт и более практически неработоспособен в сети.
Второй вопрос определяет место оптимизации для достижения максимального эффекта за определенное время. Оптимизировать приложение можно до бесконечности. Однако, как правило, на эту процедуру отводится определенное время, которое можно использовать на решение других вопросов или на разработку других приложений. Поэтому надо стремиться добиваться максимальной оптимизации минимальными усилиями. Например, если оптимизируется скорость приложения, первым делом нужно обратить внимание на циклы и на работу приложения внутри циклов, т. е. уменьшить количество шагов цикла до необходимого. И наоборот, на процедуры, вызываемые редко, следует видимо обратить внимание в последнюю очередь или вообще не оптимизировать их.
Третий вопрос подразумевает, что оптимизацию не следует проводить до бесконечности, если существуют ограничения, не связанные с работой кода приложения. Некоторые параметры приложения могут прямо зависеть от параметров системы: скорости работы диска или сети. Поэтому следует вовремя остановиться в оптимизации параметров приложения, когда ее результат уже в малой степени зависит от приложения. Например, при работе с диском таким ограничением будет скорость выполнения операций записи/чтения данных с диска.
Оптимизация скорости работы приложения
Основной способ оптимизации скорости работы — это оптимизация кода приложения. При этом желательно прислушаться к рекомендациям разработчиков Visual Basic 6.
- Избегайте переменных типа variant и присваивайте соответствующие их применению типы. При использовании в выражениях переменных типа Variant теряется время на их приведение к конкретному типу в соответствии с типом выражения. Причем, необходимо иметь в виду, что при множественном описании ключевые слова As Type относятся только к одной переменной, то есть Dim А, в, с As String означает, что А и В— переменные типа variant (по умолчанию) и только с — строковая. В этом случае лучше написать Dim A As string, в As String, с As string. Используйте для арифметических вычислений переменные типа Long или Integer, поскольку они, в отличие от currency, single или Double, более всего соответствуют машинному коду. В табл. 10.4 приведено ранжирование по относительной скорости типов переменных при арифметических вычислениях.
Таблица 10.4. Относительная скорость вычисления для типов переменных
Тип переменной |
Относительная скорость |
Long |
Самая высокая скорость |
Integer |
Ниже чем у Long |
Byte |
Ниже чем у Integer |
Single |
Ниже чем у Byte |
Double |
Ниже чем у Single |
Currency |
Самая низкая скорость |
- Назначайте часто используемое свойство объекта в переменные, так как назначение и чтение переменных работает быстрее (от 10 до 20 раз). Для сравнения приведены два примера с двумя вариантами текста кода, при этом второй вариант кода более быстрый, чем первый, и в том и в другом примере.
1. Первый пример.
Первый вариант кода:
For nCounter = 1 То 20
Object(nCounter).Property = ObjectDef. Property
Next nCounter
Второй вариант кода:
valProperty = ObjectDef. Property For nCounter = 1 To 20
Object(nCounter).Property = valProperty
Next nCounter
2. Второй пример.
Первый вариант кода:
For nCounter = 1 То 20
Object. Property = Object. Property & sValue
Next nCounter
Второй вариант кода:
For nCounter = 1 To 20
sValueAll = sValueAll & sValue
Next nCounter
Object. Property = sValueAll
- Для хранения одинаковых значений в процедурах вместо переменных типа Static используйте переменные уровня модуля, поскольку они работают быстрее. При этом, правда, текст кода приложения увеличивается за счет дублирования и становится менее читабельным и понятным. Для критичных по времени вычисления случаев используйте код процедур непосредственно в месте их выполнения взамен вызова этих процедур, который занимает определенное время. Правда при этом необходимо помнить, что размер кода увеличивается за счет дублирования кода процедур. Вместо переменных, насколько это возможно, используйте константы, поскольку значения констант включаются при компиляции в код приложения, а переменные каждый раз должны быть найдены в памяти и считаны, что, конечно, занимает определенное время.
Замечание
Оптимизация кода приложения, конечно, связана и с оптимизацией его размера. Как видно из некоторых способов оптимизации кода, размер кода либо увеличивается, либо уменьшается при оптимизации скорости приложения
Оптимизация размера приложения
При оптимизации размера приложения под размером будем понимать как размер исполняемого файла, так и размер загруженного в память приложения. Особенно критичным размер является для приложений, работающих в сети Internet. Поэтому такие приложения следует делать как можно меньшего размера. Если это не получается, можно разделить большое приложение на несколько небольших, которые будут выполнять законченные функции и загружаться по мере необходимости.
Частичную оптимизацию размера кода выполняет сам Visual Basic 6. При компиляции приложения в исполняемый файл пустые строки и строки комментариев пропускаются, поэтому на них можно не экономить. В том числе можно не экономить на длине имен идентификаторов, которые также оптимизируются компилятором.
Для оптимизации размера кода подойдут такие основные рекомендации:
- уменьшайте количество загруженных форм. Для форм, которые закрываются, применяйте оператор: set Form = Nothing; уменьшайте в формах, насколько это возможно, количество элементов управления. При этом лучше пользоваться массивами элементов управления; для вывода тестовых значений максимально используйте объекты Label вместо TextBox; для хранения данных используйте файл ресурсов и загружайте данные только при необходимости; избегайте переменных типа variant, требующих 16 байт для хранения. Для сравнения переменные типа integer требуют 2 байта, переменные типа Double — 8 байт; избегайте "мертвого" кода — то есть процедур и переменных, которые когда-то требовались, но в настоящее время не используются. Их надо удалить или закомментировать.
Оптимизация размера графики приложения
Графика занимает существенный размер приложения, поэтому важно использовать ее оптимально. Для этого подходят такие рекомендации:
- для вывода изображений используйте элемент управления типа image, а не Picture, поскольку последний имеет атрибуты окна и, соответственно требует больше ресурсов; загружайте изображения только при необходимости, а не храните их в элементах управления; если необходимость присутствия изображения не требуется, назначайте свойству Picture объектов значение Nothing: Set Object. Picture = Nothing.
Замечание
Приведенный здесь список не содержит всевозможные рекомендации и приемы оптимизации приложений. В этом вопросе помощь вам может оказать только большая практика работы с Visual Basic 6, поскольку создание оптимальных приложений сродни мастерству, оттачиваемому разработкой приложений для Visual Basic 6.
15. Основные свойства и методы объектов Screen. Примеры
Свойства объекта Screen описаны в таблице:
Свойство |
Описание |
ActiveControl |
Возвращает ссылку на элемент управления, находящийся в фокусе |
ActiveDatasheet |
Возвращает ссылку на таблицу, находящуюся в фокусе. |
ActiveForm |
Возвращает ссылку на форму, находящуюся в фокусе. |
ActiveReport |
Возвращает ссылку на отчет, находящийся в фокусе. |
Application |
Возвращает ссылку на объект Application. |
MousePointer |
Устанавливает или возвращает значение, которое определяет тип курсора мыши, отображаемого в данный момент |
Parent |
Возвращает ссылку на объект, содержащий объект Screen. |
PreviousControl |
Возвращает ссылку на предыдущий находившийся в фокусе элемент управления. |
При использовании объекта Screen целесообразно реализовать обработку ошибок, так как при выполнении Вашего кода в фокусе может оказаться не тот объект. Вероятно, лучше сначала применить метод SetFocus формы, отчета или элемента управления для установки фокуса? тогда Вы будете уверены, что в фокусе находится именно тот объект, который Вам нужен. Кроме того, старайтесь не использовать объект Screen с методом OutputTo объекта DoCmd.
Свойства ActiveForm и Me не обязательно возвращают ссылку на одну и ту же форму. Свойство Me представляет форму, чей код выполняется в данный момент, а свойство ActiveForm возвращает ссылку на форму, активную на экране, и это не всегда та форма, чей код сейчас выполняется. Допустим для примера, что в неактивной форме произошло событие Timer. Тогда свойство Me позволит сделать ссылку на форму, в которой произошло событие Timer, а свойство ActiveForm ? на форму, которая активна на экране в момент возникновения (и обработки) этого события.
В следующем примере событие Timer используется для обновления данных на активной форме через регулярные интервалы. Форма, в которой происходит событие Timer, может быть (а может и не быть) активной.
Private Sub Form_Load( )
═════Me. Timer-Interval = 30000
End Sub
Private Sub Form_Timer( )
═════Const conFormNotActive As Integer =2475
═════Const conFormInDesignView As Integer = 2478
═════On Error GoTo Error_Timer
═════? периодически запрашиваем источник записей "в интересах" активной формы
═════Screen. Active Form. Requery
═════Exit_Timer;
Exit Sub
Error_Timer:
═════If Err = conFormNotActive Or Err = conFormInDesignView Then
══════════Resume Exit_Timer
═════Else
══════════MsgBox Err & ": " & Err. Description
═════End If
End Sub
Объект Screen для пользователей Visual Basic 6.0
В Visual Basic 6.0 объект Screen предоставляет доступ к активной форме и элементу управления приложения, предоставляет сведения об области экрана, в которой отображается приложение, и позволяет изменять внешний вид курсора.
Свойство ActiveControl
В Visual Basic 6.0 свойство ActiveControl объекта Screen используется для определения элемента управления, на котором установлен фокус. Свойство ActiveControl может использоваться глобально, например в Screen. ActiveControl, где возвращается активный элемент управления на форме, выделенной в данный момент. Если обращение производится к определенной форме, например Form2.ActiveControl, свойство ActiveControl определяет элемент управления, который получит фокус, если указанная форма является активной.
Свойство ActiveForm
В Visual Basic 6.0 свойство ActiveForm объекта Screen используется для определения формы, имеющей в данный момент фокус. Если родительская форма MDI имеет фокус, ActiveForm возвращает дочернюю форму MDI, которая имела фокус до этого.
Свойство MousePointer
В Visual Basic 6.0 свойство MousePointer объекта Screen используется для изменения внешнего вида курсора. После задания оно применяется ко всем формам приложения.
Свойства TwipsPerPixel
В Visual Basic 6.0 свойства TwipsPerPixelX и TwipsPerPixelY объекта Screen используются для преобразования размерности экрана из логических твипов (стандартная единица измерения в Visual Basic 6.0) в точки.
Изменения кода для определения активного элемента управления
В следующем примере кода демонстрируется копирование текста из выделенного в данный момент элемента управления на выделенной форме в буфер обмена:
‘ Visual Basic 6.0
If TypeOf Screen. ActiveControl Is TextBox Then
Clipboard. SetText Screen. ActiveControl. Text
End If
Изменения кода для определения активной формы
В следующем примере кода демонстрируется изменение заголовка выделенной в данный момент формы:
‘ Visual Basic 6.0
Screen. ActiveForm. Caption = "This is the selected form"
Изменения кода для определения активной формы в приложении MDI
В следующем примере кода демонстрируется изменение заголовка выделенной в данный момент дочерней формы MDI:
‘ Visual Basic 6.0
Screen. ActiveForm. Caption = "This is the selected child form"
В Visual Basic существуют объекты, не отображаемые на форме, но использование которых несложно и может принести некоторую пользу. В прошлых главах мы говорили об объектах Printer, Err и DataObject. Давайте поговорим еще о некоторых.
Объект Screen
По-сути, объект Screen представляет собой весь экран или иначе Десктоп (DeskTop). Как и другие объекты, объект Screen имеет определенные свойства. Так, например, почему-то считается, что для определения разрешения экрана надо использовать API-функции. Но это прекрасно можно сделать и внутренними возможностями VB. У объекта Screen есть свойства .Height и .Width, которые и возвращают высоту и ширину экрана в твипах. Эти самые твипы легко преобразовать в пиксели, если использовать два других свойства объекта Screen — .TwipsPerPixelX (которое возвращает количество твипов в пикселе по-горизонтали) и .TwipsPerPixelY (которое возвращает количество твипов в пикселе по-вертикали). Таким образом, чтобы определить разрешение экрана, мы пишем приблизительно следующий код:
Private Sub Command1_Click() ‘Объявить переменные Dim VisotaScr As Long ‘для высоты Dim ShirinaScr As Long ‘для ширины
VisotaScr = Screen. Height / Screen. TwipsPerPixelX ‘узнаем высоту экрана и преобразовываем ее в пиксели
ShirinaScr = Screen. Width / Screen. TwipsPerPixelY ‘узнаем ширину экрана и преобразовываем ее в пиксели
Text1 = VisotaScr & " x " & ShirinaScr ‘выводим результат в Text1 End Sub
Еще одно свойство .ActiveControl содержит ссылку на элемент управления (и его свойства), имеющий фокус. Смысл использования этого свойства следующий. Например, у тебя на формe три текстбокса. И ты хочешь активный текстбокс очистить. Вот в этом случае и можно использовать свойство. ActiveControl, например
Screen. ActiveControl. Text=""
т. е. очищается тот объект ( в нашем случае TextBox) , на котором в данный момент находится фокус. Это, конечно, несколько упрощено, по-скольку, во-первых, необходимо проверить, а текстбокс ли это? Может у тебя на форме есть другие элементы, например, PictureBox. Во-вторых, реально это свойство можно использовать только в меню, так как меню не получает фокус и активным элементом остается выбранный объект. При использовании, например, свойства. ActiveControl в процедуре CommandButton, при нажатии на кнопку Command1 фокус перейдет с нужного нам элемента на командную кнопку и мы не получим желаемого результата. Ниже, в этой главе, мы на примере работы с объектом Clipboard будем использовать это свойство применительно к меню.
Аналогично свойству .ActiveControl и свойство и .ActiveForm, но содержит ссылку на активную форму. Тогда, чтобы добраться до какого-либо элемента можно применить, например, такой оператор:
Screen. ActiveForm. ActiveControl. Picture
Надо сказать, что объект Screen имеет еще свойства MouseIcon и MousePointer, которые позволяют менять вид курсора, но их использование совершенно аналогично этим свойствам для формы, которые мы анализировали в главе 5. Поэтому я не стану занимать этой дребеденью наше драгоценное время и предлагаю перейти к более нужному и интересному.
16. Основные свойства и методы объектов Clipboard. Примеры.
Сейчас мы коротенько поговорим о довольно-таки нужных текстовых свойствах, тем более, что мы будем их использовать далее при работе с объектом Clipboard. Мы уже использовали свойство SelText в прошлой главе, но на этом не остановимся. Если мы выделим кусочек текста в Text, то мы можем получить (или установить) об этом выделенном фрагменте некоторую полезную информацию как раз с помощью этих свойств:
.SelLength — возвращает или устанавливает число выделенных символов. (синтаксис объект. SelLength [= число выбранных символов])
.SelStart — возвращает или устанавливает начало выделенного текста, а если текст не выбран, то указывает положение места вставки. (синтаксис объект. SelStart [= положение начала вставки])
.SelText — возвращает или устанавливает строку, в которой содержится выделенный текст. Если никаких символов не выбрано, то представляет строку нулевой длины ("").(синтаксис объект. SelText [= текст выделения]).