Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/113: Рейтинг темы: голосов - 113, средняя оценка - 4.77
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16

[Статья] Как заставить Вашу программу на VB работать быстрее?

08.01.2015, 17:13. Показов 24459. Ответов 25
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Автор: Рут Глушкин, VBStreets

Прежде всего заставьте программу работать, а затем беспокойтесь о ее быстродействии.

Существует множество способов ускорения вашей VB программы. К сожалению, большинство из них не приводят к особо впечатляющим результатам. Даже если ваша программа работает с огромными коллекциями, преобразование их в массивы, возможно, спасет вам какой-то процент или два в процессе выполнения программы. С другой стороны, переписывание основных алгоритмов программы может сократить процесс выполнения в сотни раз.

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

1. Производя арифметические операции, оперируйте целыми числами и используйте целочисленные операторы, где это возможно. Используйте оператор "\" - целочисленного деления вместо "/" - деления с плавающей точкой. Используйте "* .5" вместо "/ 2", поскольку команда ассемблера "MUL" быстрее, чем "FDIV".

2. Где только это возможно, не применяйте квадратные корни, например:

Visual Basic
If a * a + b * b = 4 Then ...
гораздо быстрее, чем
Visual Basic
If Sqr(a * a + b * b) = 2 Then ...
3. Если Вам необходимо производить повторяющиеся вычисления как можно быстрее, наиболее эффективно создать таблицу значений функции, и просто заменять исходные данные на соответствующие результаты из этой таблицы. Например, если заранее указать в таблице x и y как координаты каждой точки на окружности на расстоянии 1-2 градуса, это будет достаточно точно и гораздо быстрее, чем вычислять их значения, используя функции SIN, COS и TAN.

4. Перепишите вашу программу на C++ или Delphi. (Это, конечно, не всегда возможно, но это - единственное решение, когда несмотря ни на что, ваша программа работает невыносимо медленно).

5. Установите у себя 5 или 6 версию VB. Программы, откомпилированные в VB с опцией Native, конечно, работают медленнее, чем программы, написанные на C++ или Delphi, но они намного быстрее, чем неоткомпилированные программы, создаваемые более ранними версиями VB.

6. Создавайте шаблоны. Пользуйтесь средствами контроля производительности для того, чтобы определить, где именно ваша программа проводит больше всего времени. Эти средства встроены в VB 4 и 5, и VB 6 Enterprise Edition. Не теряйте времени по улучшению того кода, который и так достаточно быстрый.

7. Распаковывайте графику. Всегда пользуйтесь файлами с расширением .bmp, а не запакованными .jpg или .gif файлами. Эти файлы хранятся в программе в запакованном виде, и требуется дополнительное время для их раскрытия.

8. Используйте Set your_form = Nothing, когда данная форма вам больше не нужна. Это экономит память и может сэкономить массу времени, когда у вас много форм, которые вы должны хранить в памяти. Если же у вас немного форм, гораздо эффективнее загружать их все в начале программы. Затем они будут появляться на экране быстрее, когда они вам понадобятся. Не закрывайте их до конца, вместо этого применяйте методы Hide/Show по мере необходимости.

9. Используйте массивы вместо коллекций. Массивы намного быстрее. Используйте коллекции только тогда, когда вам нужны их особые свойства, например, просмотр по ключу. Заранее определяйте массивы максимально возможного размера, чтобы не пришлось динамически выделять под них память в процессе выполнения программы - ReDim.

10. Если вам нужно обнулить все элементы динамического массива, используйте ReDim. Это займет больше времени, чем оставить массив в покое, но это гораздо быстрее, чем обнуление элементов массива в цикле.

11. Если вам нужно обнулить все элементы массива фиксированной длины, объявленного с применением Dim, используйте Erase. Это уничтожит динамический массив, но обнулит массив фиксированной длины.

12. Пользуйтесь функциями API MemCopy или RtlMoveMemory для копирования массивов вместо копирования их элементов в цикле.

13. Всегда указывайте определенные типы данных вместо Variant. Всегда объявляйте переменную вместе с ее типом. Если вы не укажете тип переменных, она по умолчанию будет Variant.

14. Всегда указывайте определенные типы объектов вместо объявления переменной типа Object. Будьте настолько точны, насколько это возможно.

Например,

Object - плохо
Control - лучше
TextBox - лучше всего.

15. Никогда не очищайте коллекцию, удаляя ее элементы. Уничтожайте их, используя Set элемент = Nothing.

16. Объявляйте объект и выделяйте под него память на отдельных строках кода. Строка "Dim obj As New MyClass" выполняется медленнее, чем две отдельных строки "Dim obj As MyClass" "Set obj = New MyClass".

17. Для проверки строки нулевой длины "" используйте функцию Len. То есть:

Visual Basic
If Len(my_string) = 0 Then ... гораздо быстрее, чем:
If my_string = "" Then
18. Используйте With для длинных последовательностей указаний свойств объектов, повторяемых несколько раз. Это выполняется быстрее, чем если вы повторите серии объектов в каждой отдельной команде.

19. Применяйте как можно меньше операций с переменными типа String, эти операции медленные.

20. Упорядочивайте команды внутри Select Case таким образом, чтобы наиболее часто встречающиеся значения были вначале.

21. Ощущаемое быстродействие гораздо важнее фактического. Представьте себе, что вы нажали на кнопку, и в течение 10 секунд ничего не происходит. Эти 10 секунд покажутся вам часом. Добавьте ProgressBar, и тогда пользователь даже не заметит, что прошло 10 секунд.

22. Когда у вас в программе множество динамически меняющихся картинок, поместите их все в невидимые Images на первую загружаемую форму, а затем загружайте их по мере необходимости. Никогда не работайте с файлами. Строка

Visual Basic
Form2.Image1.Picture = LoadPicture("yourfile.bmp")
выполняется в десятки раз медленнее, чем
Visual Basic
Form2.Image1.Picture = Form1.Image1.Picture
23. Если вам нужно производить множество операций с файлами или с переменными типа String, всегда добавляйте знак $ после имени команды, например, Mid$ вместо Mid, потому что Mid работает с параметрами типа Variant, в то время, как Mid$ работает с параметрами типа String, что в 3 раза быстрее.

24. Чтобы создать ощущение, что ваша программа выполняется быстро, показывайте первую форму как можно быстрее. Вставьте команду Show в процедуру Form1_Load(), чтобы она появилась на экране до окончания выполнения долгих начальных настроек и вычислений. Помещайте в процедуру каждой формы Load как можно меньше кода для того, чтобы она появлялась как можно быстрее. Если требуется много времени для загрузки начальной формы, создайте дополнительную форму с ProgressBar и загружайте ее немедленно. Эта форма должна быть на экране все время выполнения начальных настроек, она убирается с экрана в конце процедуры Form1_Load().

25. Распределяйте функции и процедуры по модулям. Когда одна процедура вызывает другую, загружается весь модуль второй процедуры. Если одна процедура вызывает несколько процедур из разных модулей, все эти модули загружаются в память. Если же все процедуры находятся в одном модуле, они все загружаются одновременно.

26. Не тратьте память бездумно. Иногда вы можете заставить вашу программу выполняться быстрее, используя больше памяти, но иногда применение большей памяти сильно замедляет вашу программу. В частности, если вы используете так много памяти, что ваша программа требует больше оперативной памяти, чем есть в системе, система будет загружать программу постранично, что сильно замедлит ее выполнение.

27. Для сокращения требуемой оперативной памяти присваивайте Form1.AutoRedraw = False.

Но для ускорения сложных графических операций присваивайте Form1.AutoRedraw = True.

28. Присваивайте Object.ClipControls = False, где это возможно (прочтите Help для более подробной информации).

29. Для изменения местоположения контролек используйте команду Move вместо изменений значений Left и Top.

30. Если вам нужно изменить серию свойств, связанных с внешним видом (Appearance) объекта, вначале сделайте его невидимым, и только по завершении всех операций, сделайте его снова видимым.

31. Кэшируйте свойства, которые вы применяете много раз. Например, если ваша программа несколько раз обращается к свойству txtLastName.Left, поместите это значение в переменную, и работайте с ней. Обращение к переменной намного быстрее, чем к свойствам объекта.

32. Для того, чтобы нарисовать прямоугольник, вместо четырех команд Line, используйте:
Visual Basic
Line (x1, y1)-(x2, y2), , B
33. Вместо PictureBoxes применяйте, где это возможно, Images, поскольку Image требует гораздо меньше памяти.

34. Используйте Frames для хранения других объектов вместо PictureBoxes, так как Frame требует меньше памяти.

35. Неважные объекты помещайте в массивы. Например, множество форм содержат множество Labels. Поместите их все в один массив. Массив, содержащий 10 объектов, требует меньше памяти, чем 10 отдельных объектов.

36. Выполняйте длинные вычисления на фоне выполнения других операций, используя Timer.

37. Используйте комментарии и значимые имена переменных. Длинные комментарии и имена переменных, а также пустые строки не увеличивают размера вашей программы, так что нет никакого вреда в их применении.

38. Не нумеруйте каждую строку вашего кода, поскольку нумерация строк увеличивает размер вашей программы.

39. Убирайте неиспользуемые переменные и участки кода, так как они остаются в программе, и увеличивают как ее размер, так и выделяемую под нее оперативную память.

40. Используйте DoEvents, чтобы позволить пользователю выполнять другие операции, пока ваша программа выполняет какой-то длительный процесс. Это уменьшит недовольство пользователя даже, если это не заставит вашу программу выполняться быстрее.

41. Используйте функции API FindFirstFile, FindNextFile, и FindClose для быстрого поиска файлов и папок. Но помните, что не всегда обращение к функциям API быстрее. Это всегда сложнее, и иногда весьма рискованно, чем применение стандартных функций VB.

42. Функции UCase$ и LCase$ позволяют вам осушествлять сравнения вне зависимости от регистра текста, но нижеследующие функции API гораздо быстрее:

Visual Basic
Declare Function CharLower Lib "user32" _
Alias "CharLowerA" (ByVal lpsz As String) As String
 
Declare Function CharUpper Lib "user32" _
Alias "CharUpperA" (ByVal lpsz As String) As String
43. Используйте временные переменные для многократного обращения к сложным выражениям. Например, вам нужно присвоить различные значения объекту
SelectedEmployee.NextOfKin.HomeInformati on.Address. Вместо того, чтобы обращаться к этому длинному выражению несколько раз, используйте:

Visual Basic
Dim addr As AddressInfo
Set addr = SelectedEmployee.NextOfKin.HomeInformation.Address
addr.Street = txtStreet.Text
addr.City = txtCity.Text
addr.State = txtState.Text
addr.Phone = txtPhone.Text
Команда With дает такое же ускорение, поэтому вы можете использовать:
Visual Basic
With SelectedEmployee.NextOfKin.HomeInformation.Address
.Street = txtStreet.Text
.City = txtCity.Text
.State = txtState.Text
.Phone = txtPhone.Text
End With
44. При вызове процедуры или функции, где это возможно, передавайте параметры ByRef, а не ByVal. Когда вы используете ByRef, программа передает только небольшой адрес переменной. Когда же вы используете ByVal, программа должна создать новую копию передаваемой переменной. Обычно гораздо быстрее передать адрес, чем создать копию переменной. Однако, когда вы формируете вызов функций, относящихся к разным процессам, ByVal выполняется быстрее. При таком вызове, VB должен в любом случае запаковать значение переменной для передачи ее другому процессу. Если вы используете ByRef, VB должен затем распаковать результат, и это отнимает больше времени.

45. Для вычисления степеней используйте оператор "*" вместо "^".

Например, A = B * B быстрее, чем A = B ^ 2.

46. Если вам нужно сформировать длинную строку, формируйте ее по частям, и затем собира йте все части воедино. Например, у вас есть процедуры AddText1, AddText2, и т.д., которые добавляют текст к переменной типа String.

Тогда этот код:

Visual Basic
Dim txt As String
txt = AddText1(txt)
txt = AddText2(txt)
txt = AddText3(txt)
будет выполняться медленнее, чем следующий:
Visual Basic
Dim txt As String
Dim txt1 As String
Dim txt2 As String
Dim txt3 As String
AddText1(txt1)
AddText2(txt2)
AddText3(txt3)
txt = txt1 & txt2 & txt3
В первом примере, процедуры AddText должны манипулировать длинными строками. Во втором примере они работают с относительно короткими строками.

47. Запоминайте промежуточные результаты математических вычислений.

Например, этот код:
Visual Basic
Xsquare = x * x
Ysquare = y * y
a = 2 * Xsquare + 3 * Ysquare
b = 3 * Xsquare + 5 * Ysquare
If a + b > 50 Then ...
выполняется быстрее, чем следующий:
Visual Basic
If 2 * x * x + 3 * y * y + _
3 * x * x + 5 * y * y > 50 _
Then ...
48. Не вставляйте в цикл проверку со значением, возвращаемым функцией.

Например, этот код:
Visual Basic
i = 1
Do While i
выполняется значительно медленнее, чем этот:
Visual Basic
i_max = SlowFunction()
i = 1
Do While i
Примечание: цикл For не пересчитывает свои границы каждый раз. Когда цикл For начинается, система определяет граничные значения и запоминает их. Она не будет пересчитывать их каждый виток цикла. Следовательно, нижеследующий код выполняется достаточно быстро:
Visual Basic
For i = 1 To SlowFunction()
total = total + i
Next i
9
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.01.2015, 17:13
Ответы с готовыми решениями:

Как заставить функцию работать быстрее?
Может кто подсказать в плане оптимизации как заставить функцию Check() работать быстрее? Применил StringBilder вместо string, код стал...

Оцените, будьте так любезны! Как заставить игры работать чуточку быстрее на таком компьютере?
---------------------------------- 01 - Операционная система ---------------------------------- 0101 - Операционная система :...

Можно ли заставить ЖД работать быстрее?
Подключил я внешний хард ко второму пню, чтобы перегнать туда инфу с компа, но появилась надпись типа винт работает медленно. Перетыкнул на...

25
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
19.12.2017, 16:02  [ТС]
Студворк — интернет-сервис помощи студентам
http://www.xbeat.net/vbspeed/
0
0 / 0 / 0
Регистрация: 27.03.2014
Сообщений: 25
12.11.2019, 11:05
Уважаемы коллеги, тема про быстродействие, так что позволю себе тут.
В связи с переходом на офис-365 VBA под ЭКСЕЛЬ стал зависать. Вот именно висеть по нескольку часов, иногда ночь. Иногда потом он отвисает, иногда нет. Одна и та же программа может сегодня висеть а завтра нет. Ситуация возникает на разных компьютерах с разными программами.
Ни у кого не случалось победить что-то похожее?
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
12.11.2019, 16:09  [ТС]
Это вы явно не в тему. Здесь обсуждается код, а не проблемы с ОС.
Проверьте на вирусы. Обратитесь в раздел форума по софту, по ОС. Почистите лишние программы.
0
Заблокирован
03.04.2020, 10:10
Всем приятного времени суток и благополучного пережития эпидемии.

Наверняка большинство из нас сталкивалось с конкатенацией строк в цикле и сопутствующими потерями времени на их выполнение.
Для примера
Visual Basic
1
2
3
For i = 0 To 59999
    s = s & ":" & i
Next i
Как можно в два и более раз ускорить сей процесс?

Не по теме:

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


Помогут здесь всего лишь правильно поставленные скобки.
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sub main()
s = ""
t = Timer
For i = 0 To 59999
    s = s & ":" & i
Next i
Debug.Print Timer - t & " сек" '17,23438 сек
 
s = ""
t = Timer
For i = 0 To 59999
    s = s & (":" & i)
Next i
Debug.Print Timer - t & " сек" '7, 46875; сек
 
End Sub
2
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
03.04.2020, 11:05  [ТС]
Ну это легко объяснимо, если разложить операцию:

В первом случае:
Code
1
s = s & ":" & i
это
Code
1
2
s = s & ":"
s = s & i
т.е. 1 символ дважды прибавляется к длинной строке

Во втором случае:
Code
1
s = s & (":" & i)
это
Code
1
2
tmp = ":" & i
s = s & tmp
Сперва складываются две короткие строки
А уж затем результат прибавляется к длинной строке.

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

Приведенная вами логика похожа на предварительное создание log-файла в памяти с постоянной дозаписью, прежче чем он в итоге сбрасывается на диск.
Для подобных операций я писал класс StringBuilder, где буфер выделяется заранее и дозапись идёт путем записи в этот буфер без повторного выделения памяти, т.е. достигается максимально возможная скорость.
Использовать его довольно просто, поэтому из-за того что он написан на основе WinAPI когнитивного диссонанса возникнуть не должно

Но если нужно что-то более простое и без WinAPI, то VB6 позволяет писать сразу в выделенный буфер такой командой:

Visual Basic
1
2
3
4
5
    Dim buf As String * 16
    
    Mid$(buf, 4) = "hello"
    
    Debug.Print buf
при этом для переменной buf память повторно не выделяется.
Из минусов, необходимо заранее выделить буфер максимальной расчётной длинны, либо увеличивать его порциями.
Поэтому для более сложных приложений, проще все таки просто подключить готовый и проверенный временем класс.
2
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,787
02.03.2023, 00:18
Цитата Сообщение от The trick Посмотреть сообщение
Для копирования данных от 1 до 8 байт используйте функции GetMem
Я немного переделал твой проект GetMemOptimize, для интереса, подключил в него библиотеку TLB, которую самому пришлось написать, с функцией GetMem4. Как результат стало работать ещё в 2 раза быстрее, когда GetMem4 выполняется из TLB. Нет предела совершенству)))
3
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.03.2023, 00:18
Помогаю со студенческими работами здесь

Как заставить программу работать с консолью?
Как сделать что бы моя прога работала с консолью(то есть могла посылать запросы в консоль и читать их от туда)?

Как заставить программу работать постоянно?
Здравствуйте! Мне нужно сделать так, что бы программа работала постоянно. Я уже попытался закинуть её в автозагрузку - но она,...

Как заставить эту программу работать в VC++ форм
Уважаемые программисты помогите, срочно нужен ответ #include <vcl.h> #pragma hdrstop #include «Unit21.h» // – #pragma package...

Как заставить программу работать через прокси?
Кто нибудь имеет примерчик как заставить готовую прогу (типа чата) работать с возможностью прокси? А то машины к инету через проксю...

Как заставить программу работать без остановки?
Здравствуйте, недавно начал изучать objective-c. И вот вопрос, например есть код и как его работать без остановки, а то я ввожу value1 и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
Новые блоги и статьи
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru