Безопасность vs Производительность.

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Безопасность vs Производительность.

Сообщение Mikle » 03.03.2017 (Пт) 14:55

У меня задача:
В проекте может быть множество Single массивов, все одинакового размера. С массивами выполняются разнообразные простые операции, например, массивы можно почленно сложить или перемножить.
Эти действия оформлены в отдельные процедуры. Крайне желательно, чтобы при наборе кода, использующего процедуры, работал IntelliSense, и чтобы процедуры не принимали параметром другие Single массивы.
Я обернул массив в тип:
Код: Выделить всё
Public Type tTF
  Ar() As Single
End Type

Так выглядит процедура сложения массивов:
Код: Выделить всё
Public Sub tTFAdd(Dst As tTF, Src1 As tTF, Src2 As tTF)
  Dim i As Long

  For i = 0 To TFSize - 1
    Dst.Ar(i) = Src1.Ar(i) + Src2.Ar(i)
  Next i
End Sub

TFSize, как нетрудно догадаться, это общий размер массивов.
Работает быстро, ничего лишнего в процедуру не подсунешь, но такой подход вынуждает каждый массив инициализировать:
Код: Выделить всё
Public Sub tTFNew(T As tTF)
  ReDim T.Ar(TFSize - 1)
End Sub

Эту инициализацию можно случайно пропустить - получим ошибку. Я мог бы в типе указать сразу фиксированный размер массива, но VB6 не даёт задавать в типе фиксированный размер более 64 Кб, что крайне мало.
Тогда я решил завернуть массивы не в тип, а в класс. Но в классе нельзя сделать Public массив, приходится делать свойство для доступа к элементам массива. Защищенность повысилась, теперь массив инициализируется автоматически, но скорость упала в 35-40 раз, а для меня этот параметр очень важен.
Подскажите, есть ли ещё какой-то путь решения моей задачи, который я упустил?
Прилагаю тестовый проект:
Вложения
SpdTest.zip
(6.06 Кб) Скачиваний: 161

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Безопасность vs Производительность.

Сообщение alibek » 03.03.2017 (Пт) 18:32

А возможно вынести инициализацию в On Error?
Lasciate ogni speranza, voi ch'entrate.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Безопасность vs Производительность.

Сообщение Mikle » 03.03.2017 (Пт) 19:21

Я включаю оптимизацию "Remove Array Bounds Checks", при такой работе с массивами это немалая прибавка скорости.

kibernetics
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 945
Зарегистрирован: 03.05.2006 (Ср) 13:31
Откуда: Minsk

Re: Безопасность vs Производительность.

Сообщение kibernetics » 03.03.2017 (Пт) 22:38

Mikle писал(а):Эту инициализацию можно случайно пропустить - получим ошибку.

А если сделать проверку инициализирован ли массив, то тоже жрётся производительность?

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Безопасность vs Производительность.

Сообщение Mikle » 04.03.2017 (Сб) 11:51

kibernetics писал(а):А если сделать проверку инициализирован ли массив, то тоже жрётся производительность?

Не особо жрётся. Можно даже проверку на инициализацию сделать не известным здесь хаком, а добавлением в тип Long элемента с размером массива, в процедурах проверять эту переменную и редимить при необходимости, а для редима сделать процедуру, типа Sub TFReSize (T As tTF)в ней редимить массив и в переменную записывать соответствующее значение.

Вообще, в идеале, было бы хорошо иметь возможность менять TFSize в середине программы, так, чтобы размер всех массивов при этом тоже менялся, пусть с потерей данных. Вижу это в случае, когда массив обёрнут в класс, класс в Initialise автоматически регистрируется в некой коллекции, для смены TFSize есть процедура TFReSize (общая, в модуле), эта процедура проходит по коллекции и редимит все массивы. Если создавать классы-массивы As New, то дальше всё работает красиво, автоматически и без излишеств, только вот вопрос быстродействия остаётся. Можно, разве что, с помощью CopyMemory (или с помощью Friend процедуры в классе, возвращающей массив) дублировать массивы в модуль, но это тоже как-то некрасиво и много лишних телодвижений.

kibernetics
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 945
Зарегистрирован: 03.05.2006 (Ср) 13:31
Откуда: Minsk

Re: Безопасность vs Производительность.

Сообщение kibernetics » 04.03.2017 (Сб) 12:09

Mikle писал(а):Не особо жрётся. Можно даже проверку на инициализацию сделать не известным здесь хаком, а добавлением в тип Long элемента с размером массива, в процедурах проверять эту переменную и редимить при необходимости, а для редима сделать процедуру, типа Sub TFReSize (T As tTF)в ней редимить массив и в переменную записывать соответствующее значение.

Может по-простому? По-народному?
Последний раз редактировалось kibernetics 04.03.2017 (Сб) 14:28, всего редактировалось 1 раз.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Безопасность vs Производительность.

Сообщение Mikle » 04.03.2017 (Сб) 13:42

kibernetics писал(а):Может по-простому? По-народному?

Я про этот хак и писал. После этого всё равно нужно ещё размер сравнить.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Безопасность vs Производительность.

Сообщение Mikle » 04.03.2017 (Сб) 14:29

Попробовал CopyMemory, потеря быстродействия более, чем вдвое. Проект прилагаю:
Вложения
SpdTest2.zip
(6.78 Кб) Скачиваний: 147

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Безопасность vs Производительность.

Сообщение Mikle » 10.03.2017 (Пт) 9:38

Нашёл приемлемое решение, без трюков не обошлось, но, вроде бы, получилось безопасно, по крайней мере программа работает в EXE со всеми оптимизациями и в отладчике, выдерживает Stop. Память не течёт.
По сравнению с массивом в модуле теряется где-то 8% быстродействия:
Вложения
SpdTest3.zip
(6.5 Кб) Скачиваний: 151

Old_Maple
Обычный пользователь
Обычный пользователь
 
Сообщения: 54
Зарегистрирован: 25.10.2016 (Вт) 12:03

Re: Безопасность vs Производительность.

Сообщение Old_Maple » 17.03.2017 (Пт) 13:59

Mikle, а вот интересно, можно ли что-нибудь аналогичное придумать для передачи больших массивов (Single, Double) в мультипотоки для параметра (выделенного красным) вызываемой функции:
CreateThread (lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal dwStackSize As Long, lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
чтобы, например, проводить матричные вычисления и т.п.? Так как обертка в Public\Private Type---End Type действительно ограничена 64k.
Veritas est aeterna!


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот, SemrushBot и гости: 49

    TopList