Размещение массива в RAM

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
uk8amk
Обычный пользователь
Обычный пользователь
 
Сообщения: 67
Зарегистрирован: 26.07.2007 (Чт) 16:52
Откуда: Tashkent

Размещение массива в RAM

Сообщение uk8amk » 14.03.2009 (Сб) 12:39

Для работы векторного редактора требуется в ОЗУ разместить массив векторов как буфер с максимально возможным размером(720КБ). Попытка это сделать вызывает следующую ошибку:

Ошибка компиляции:
Фиксированные или статические данные не могут быть большие чем 64КБ


Вот код модуля:
Код: Выделить всё
Type PointBuffer
    X(1) As Byte
    Y(1) As Byte
    Z(1) As Byte
    ColorIndex As Byte
    RedIntensity As Byte
    GreenIntensity As Byte
    BlueIntensity As Byte
    Status As Byte
End Type

Type FrameBuffer
    FrameFormat As Byte
    TotalPoints As Long
    PointData(65535) As PointBuffer
End Type

Public RAMBuffer As FrameBuffer


Вопрос: как и чем лечить такую ошибку? Или может есть более подходящий путь размещения данных.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Размещение массива в RAM

Сообщение jangle » 14.03.2009 (Сб) 13:03

Код: Выделить всё
Option Explicit

Type PointBuffer
    X(1) As Byte
    Y(1) As Byte
    Z(1) As Byte
    ColorIndex As Byte
    RedIntensity As Byte
    GreenIntensity As Byte
    BlueIntensity As Byte
    Status As Byte
End Type

Type FrameBuffer
    FrameFormat As Byte
    TotalPoints As Long
    PointData() As PointBuffer
End Type

Public RAMBuffer As FrameBuffer


Sub MAIN()
    ReDim Preserve RAMBuffer.PointData(65535)
End Sub

uk8amk
Обычный пользователь
Обычный пользователь
 
Сообщения: 67
Зарегистрирован: 26.07.2007 (Чт) 16:52
Откуда: Tashkent

Re: Размещение массива в RAM

Сообщение uk8amk » 14.03.2009 (Сб) 13:36

Да, чето не подумал что можно его объявить динамически.
Один доп вопрос: что делает спецификатор Preserve, во встроенной стправочной системе его нет.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Размещение массива в RAM

Сообщение ANDLL » 14.03.2009 (Сб) 14:02

Копирует старое содержимое. Здесь он абсолютно не в тему
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Размещение массива в RAM

Сообщение jangle » 14.03.2009 (Сб) 14:22

uk8amk писал(а):Да, чето не подумал что можно его объявить динамически.
Один доп вопрос: что делает спецификатор Preserve, во встроенной стправочной системе его нет.


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

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Размещение массива в RAM

Сообщение iGrok » 14.03.2009 (Сб) 14:46

jangle писал(а):Но это только, если ты хочешь сэкономить ресурсы системы, в противном случае, Preserve использовать не нужно

Прости, а в чём в данном случае заключается экономия ресурсов?
label:
cli
jmp label

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Размещение массива в RAM

Сообщение jangle » 14.03.2009 (Сб) 15:22

iGrok писал(а):
jangle писал(а):Но это только, если ты хочешь сэкономить ресурсы системы, в противном случае, Preserve использовать не нужно

Прости, а в чём в данном случае заключается экономия ресурсов?


В том, что по мере поступления данных, ты "вручную" увеличиваешь массив. При хранении данных в десятки мегов это может сэкономить ресурсы

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Размещение массива в RAM

Сообщение ANDLL » 14.03.2009 (Сб) 15:27

Сказанное jangle - бред сивой кобылы.
Чем больше массив который нужно ресайзить, тем больше по времени требует Preserve. Если же массив не простых типов, а стрингов или еще хуже, object'ов то медлительность preserve просто зашкаливает
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Размещение массива в RAM

Сообщение iGrok » 14.03.2009 (Сб) 16:36

jangle писал(а):В том, что по мере поступления данных, ты "вручную" увеличиваешь массив. При хранении данных в десятки мегов это может сэкономить ресурсы

jangle, а ты не в курсе, как работает Preserve? Ты не знаешь, что при этом фактически создаётся новый массив нужного размера, после чего туда просто копируется содержимое старого, и старый удаляется?
А в предложенном тобой во втором посте коде Preserve при ReDim'е ранее пустого массива просто ни к чему..
label:
cli
jmp label

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Размещение массива в RAM

Сообщение jangle » 14.03.2009 (Сб) 17:02

Господа, прекратите постить откровенный бред. Ваша техническая безграмотность просто поразительна!
Если вы не знаете основ работы с памятью в Win32 - это ваши проблемы. Тогда лучше не лезьте в темы, в которых ничего не понимаете.
Для примера, скорость увеличения массива с Preserve - 47 мсек, а обычным Redim - 12288 мсек.
Почему это происходит, пусть будет вашим домашним заданием. :mrgreen:

Код: Выделить всё
Option Explicit
Declare Function GetTickCount Lib "KERNEL32.DLL" () As Long
Const maxtest = 65000

Type PointBuffer
    X(1) As Byte
    Y(1) As Byte
    Z(1) As Byte
    ColorIndex As Byte
    RedIntensity As Byte
    GreenIntensity As Byte
    BlueIntensity As Byte
    Status As Byte
End Type

Type FrameBuffer
    FrameFormat As Byte
    TotalPoints As Long
    PointData() As PointBuffer
End Type

Dim RAMBuffer As FrameBuffer
Dim RAMBuffer2 As FrameBuffer

Sub Main()
Dim t As Long
Dim u As Long
Dim i As Long

u = GetTickCount

     For i = 1 To maxtest
       
'-----------------------------------------------
    ReDim Preserve RAMBuffer.PointData(i)
'------------------------------------------------
     Next i
     u = GetTickCount - u
     MsgBox (u) & "-мсек скорость увеличения массива с Preserve"
     u = GetTickCount
     For i = 1 To maxtest
'-----------------------------------------------
    ReDim RAMBuffer2.PointData(i)

'------------------------------------------------
     Next i
     u = GetTickCount - u
     MsgBox (u) & "-мсек скорость увеличения массива простым Redim`om "
     
     
End Sub
Вложения
redim.zip
(1.29 Кб) Скачиваний: 138

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

Re: Размещение массива в RAM

Сообщение alibek » 14.03.2009 (Сб) 21:01

В данном случае, бред — это вот эта фраза:
jangle писал(а):В том, что по мере поступления данных, ты "вручную" увеличиваешь массив. При хранении данных в десятки мегов это может сэкономить ресурсы
Lasciate ogni speranza, voi ch'entrate.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16489
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Размещение массива в RAM

Сообщение Хакер » 14.03.2009 (Сб) 21:02

jangle писал(а):Господа, прекратите постить откровенный бред. Ваша техническая безграмотность просто поразительна!
Если вы не знаете основ работы с памятью в Win32 - это ваши проблемы. Тогда лучше не лезьте в темы, в которых ничего не понимаете.

Мальчик, а ты юморист.

Но смешить людей, вещая бред, совсем не юмористский талант.

Во-первых, ты специально сгенерировал такой пример, на котором получится нужный тебе результат.

Во-вторых, никакой связи между менеджментом памяти Win32 и результатами работы твоего примера нет.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Размещение массива в RAM

Сообщение jangle » 14.03.2009 (Сб) 21:30

alibek писал(а):В данном случае, бред — это вот эта фраза:
jangle писал(а):В том, что по мере поступления данных, ты "вручную" увеличиваешь массив. При хранении данных в десятки мегов это может сэкономить ресурсы


Не согласен, у меня был опыт в создании компонента для хранения данных трехмерки. Каждая моделька от 30 до 100 мегабайт.
Методом проб и исключений было установлено, что динамические массивы изменяемые "вручную" в итоге дают более быстрое и менее ресурсоемкое приложение.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Размещение массива в RAM

Сообщение jangle » 14.03.2009 (Сб) 21:33

Хакер писал(а):Но смешить людей, вещая бред, совсем не юмористский талант.

Во-первых, ты специально сгенерировал такой пример, на котором получится нужный тебе результат.

Во-вторых, никакой связи между менеджментом памяти Win32 и результатами работы твоего примера нет.


Я специально сгенерировал? Этоже смешно Хакер, в приложении всего несколько строчек. :mrgreen:
Просто пример чтобы показать, что простое увеличение уже выделенного блока памяти (Redim Preserve) работает намного быстрее, чем каждый раз уничтожение и выделение этого-же участка заново (Redim)

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Размещение массива в RAM

Сообщение Debugger » 14.03.2009 (Сб) 21:54

Код: Выделить всё
Sub Main()
    Dim t As Currency
    Dim arr() As Long
    Dim c As Integer
   
    t = Timer
    For c = 0 To 10000
        ReDim arr(0)
        ReDim arr(10000)
    Next
    MsgBox Timer - t
   
   
    t = Timer
    For c = 0 To 10000
        ReDim Preserve arr(0)
        ReDim Preserve arr(10000)
    Next
    MsgBox Timer - t
End Sub

Вот мой код. Не понятно, почему Redim Preserve может действовать быстрее. У него нет на это причин. Вот действия, которые выполняет Redim простой:
1) Создает новый массив с новым кол-вом элементов
2) Освобождает старый
Может быть, что-то достаточно важное я упустил, ну и ладно. Посмотрим на выполнение действий ReDim
1) Создает новый массив с новым кол-вом элементов
2) Копирует все старые элементы в новый массив
3) Освобождает старый
Таким образом, добавился 2й шаг. Он будет выполняться несколько больше (у меня - в 1,5 - 2 раза), чем ReDim простой.
Просто пример чтобы показать, что простое увеличение уже выделенного блока памяти (Redim Preserve) работает намного быстрее, чем каждый раз уничтожение и выделение этого-же участка заново (Redim)

Это лишь доказывает твою неопытность в плане памяти. А ведь еще хвалился. ReDim Preserve не будет "увеличивать массив на единичку". Причина простая. В ячейках памяти, которые ReDim захочет "съесть", может лежать какая-то другая переменная. И что с ней делать?

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Размещение массива в RAM

Сообщение jangle » 14.03.2009 (Сб) 22:12

Debugger - ты условие задачи смотрел? Первый пост... Вот твой примерчик, почувствуй как говорится разницу:

Код: Выделить всё
Option Explicit


Type PointBuffer
    X(1) As Byte
    Y(1) As Byte
    Z(1) As Byte
    ColorIndex As Byte
    RedIntensity As Byte
    GreenIntensity As Byte
    BlueIntensity As Byte
    Status As Byte
End Type

Type FrameBuffer
    FrameFormat As Byte
    TotalPoints As Long
    PointData() As PointBuffer
End Type

Dim RAMBuffer As FrameBuffer
Dim RAMBuffer2 As FrameBuffer

Sub Main()
    Dim t As Currency
    Dim c As Long
   
    t = Timer
    For c = 0 To 10000
        ReDim RAMBuffer.PointData(c)
    Next
    MsgBox Timer - t
   
   
    t = Timer
    For c = 0 To 10000
        ReDim Preserve RAMBuffer2.PointData(c)
    Next
    MsgBox Timer - t
End Sub

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Размещение массива в RAM

Сообщение Debugger » 14.03.2009 (Сб) 22:20

А что, условие как-то меняет принципы работы Redim [Preserve]?

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Размещение массива в RAM

Сообщение ANDLL » 14.03.2009 (Сб) 22:23

Ну вообще результаты джангла достаточно неожиданны. Можно даже простить ему хамский тон.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Размещение массива в RAM

Сообщение jangle » 14.03.2009 (Сб) 22:24

Debugger писал(а):А что, условие как-то меняет принципы работы Redim [Preserve]?


То, что на сложных структурах Redim [Preserve] работает быстрее обычного Redim, я заметил уже давно. Когда занимался профилированием своих приложений. Ты ведь, знаешь что такое - профилирование? :wink:

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16489
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Размещение массива в RAM

Сообщение Хакер » 14.03.2009 (Сб) 22:27

jangle писал(а):Я специально сгенерировал? Этоже смешно Хакер, в приложении всего несколько строчек. :mrgreen:

А там и не должно быть ста тысяч строчек.

Ни одному нормальному человеку в голову не придёт 65000 раз редимить массив, всякий раз увеличивая его размер на 1 элемент. А тебе в голову это пришло рассмотреть в качестве примера.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Размещение массива в RAM

Сообщение jangle » 14.03.2009 (Сб) 23:00

ANDLL писал(а):Ну вообще результаты джангла достаточно неожиданны. Можно даже простить ему хамский тон.


Это ты наверное про - бред сивой кобылы? :mrgreen:

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Размещение массива в RAM

Сообщение jangle » 14.03.2009 (Сб) 23:03

Хакер писал(а):
jangle писал(а):Я специально сгенерировал? Этоже смешно Хакер, в приложении всего несколько строчек. :mrgreen:

А там и не должно быть ста тысяч строчек.

Ни одному нормальному человеку в голову не придёт 65000 раз редимить массив, всякий раз увеличивая его размер на 1 элемент. А тебе в голову это пришло рассмотреть в качестве примера.


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

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Размещение массива в RAM

Сообщение arthur2 » 14.03.2009 (Сб) 23:12

Хакер писал(а):Ни одному нормальному человеку в голову не придёт 65000 раз редимить массив, всякий раз увеличивая его размер на 1 элемент. А тебе в голову это пришло рассмотреть в качестве примера.


Ну ладно, в обоих циклах поставлю step 100, всё равно ведь с preserve получается значительно быстрее!

По-моему, пример очень даже впечатляющий. Лучше бы объяснил, как так получается :)

Я изменил опыт: к 65000 добавил нолик, а шаг установил в 1000 - при этих условия простой редим всё же догнал того, что с preserve и даже чуточку обогнал.

Хотелось бы понять, как это работает, чтобы знать, как это применить :)
Артур
 
   

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Размещение массива в RAM

Сообщение Debugger » 14.03.2009 (Сб) 23:37

Мое предположение. Redim Preserve все таки расширяет массив. Именно расширяет, а не создает новый. Ну, если после него в памяти ничего не записано. Ну а что делает Redim - понятно из ваших тестов. Таким образом, если мы изгадим память другими переменными (ну правда это надо хорошо ее так), Redim Preserve будет таки копироваться на новое место.
Интересно, String тоже по такому принципу работает?
P.S. Моя теория верна?
Последний раз редактировалось Debugger 14.03.2009 (Сб) 23:37, всего редактировалось 1 раз.

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

Re: Размещение массива в RAM

Сообщение alibek » 14.03.2009 (Сб) 23:37

jangle писал(а):Ты ведь, знаешь что такое - профилирование? :wink:

Ты ведь знаешь, что правильно говорить профайлинг?
Lasciate ogni speranza, voi ch'entrate.

Йода
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 99
Зарегистрирован: 06.01.2008 (Вс) 21:04
Откуда: Московская область

Re: Размещение массива в RAM

Сообщение Йода » 15.03.2009 (Вс) 0:05

Насколько я понимаю, и Redim и Redim Preserve сводятся к вызову функции SafeArrayRedim, которая размещает и инициализирует новые элементы массива,(без создания нового массива и копирования данных из старого) сохраняя при этом данные. То есть при использовании Redim нужно не только вызвать SafeArrayRedim, ещё и очистить данные массива (на что естественно требуется определённое время). Наверное это и объясняет результаты теста. З.Ы. Всё вышесказанное - ИМХО.
Sub or Function not defined

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16489
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Размещение массива в RAM

Сообщение Хакер » 15.03.2009 (Вс) 1:07

Объясню.

Во-первых, в данном примере всё было сделано так, чтобы возникли все необходимые факторы для того, чтобы получился именно такой результат, который получился.

И самая главная глупость — многократное изменение размера массива на всего-лишь один элемент. Артур2, Step 100 не изменяет этого факта.

Так вот, грубый ReDim (т.е. оный без Preserve) должен "занулять" все элемента массива.
Мягкий ReDim (т.е. ReDim Preserve) должен "занулять" только добавленные элементы.

Пример jangla показывает только одно: произвести N занулений будет быстрее, чем произвести (N2 + N)/2 занулений. Это очевидно и без примера.

Во-вторых, jangle обвинял тут всех, кто высказались "против него", в незнании механизмов управления памятью в Win32. Как я показал выше, разница в результатах обусловлена исключительно разным количеством занулений. Механизмы управления памятью тут непричём.

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

Тут есть два принципиально разных вариантов развития событий:
  • В куче после текущего блока памяти окажется достаточно свободного места, чтобы можно было засчёт него расширить текущий блок. Тогда блок просто расширяется.
  • В куче после текущего блока идёт другой блок, причём так близко к текущему, что расширить текущий блок до нужных размеров так, чтобы он не перекрыл другие блоки — невозможно. Тогда текущий блок переезжает в другое место кучной памяти.
В последнем случае тратится больше ресурсов (да, jangle!), потому что одновременно в памяти должны существовать два блока памяти: блок старого массива старого размера и блок нового массива нового размера — чтобы скопировать данные из старого массива в новый. Так что если мы превращаем 490мб-массив в 500-мб массив, то в некоторый момент у нас будет занято 990 метров кучной памяти.
Экономия ресурсов, да?

Но здесь мы имеем особую атмосферу проведения эксперимента:
1) В проекте один лишь эксперимент, он совершается в самом начале работы программы, а значит куча изначально не фрагментирована.
2) Постоянные редимы делаются в цикле. Между редимами никаких иных действий не совершается, а значит в процессе работы никто не сможет фрагментировать кучу.

Таким образом, я с 95% вероятностью могу утверждать, что все ReDim-ы в примере jangle-а идут по первому варианту развития событий, без реаллокации (в прямом смысле), а значит очень быстро.

Плюс к этому у jangle-а используется психологический эффект: структура имеет кучу полей. На самом деле все поля байтовые и их 8. Элемент массива занимает всего-лишь 8 байтов. Учитывай, что Heap(Re)Alloc может прихватывать справа ещё и чуть-чуть памяти, то даже в случае очень сильной фрагментации достаточно большое кол-во редимов пройдёт без необходимости релокации блока.

Всё то же самое, будь оно внутри реальной программы, в которой по своим законам создаются и уничтожаются объекты, а значит, в которой постоянно фрагментируется куча, в которой массив расширяется не по одному элементу, а достаточно большими блоками — результат был бы обратным.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

FaKk2
El rebelde gurú
El rebelde gurú
Аватара пользователя
 
Сообщения: 2031
Зарегистрирован: 09.03.2003 (Вс) 22:10
Откуда: Los Angeles

Re: Размещение массива в RAM

Сообщение FaKk2 » 15.03.2009 (Вс) 1:54

Спасибо, Хакер. Очень внятно обьяснил.
Для получения ответа надо продемонстрировать качества, позволяющие стать компетентным — внимательность, вдумчивость, наблюдательность, желание активно участвовать в выработке решения.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Размещение массива в RAM

Сообщение jangle » 15.03.2009 (Вс) 3:11

Йода писал(а):Насколько я понимаю, и Redim и Redim Preserve сводятся к вызову функции SafeArrayRedim, которая размещает и инициализирует новые элементы массива,(без создания нового массива и копирования данных из старого) сохраняя при этом данные. То есть при использовании Redim нужно не только вызвать SafeArrayRedim, ещё и очистить данные массива (на что естественно требуется определённое время). Наверное это и объясняет результаты теста. З.Ы. Всё вышесказанное - ИМХО.


Совершенно верно! Полное попадание в яблочко ))) Функция Redim Preserve в VB реализована через вызов SafeArrayRedim из OLEAUT32.DLL
Никаких функций типа HeapAlloc при этом не используется. Кстати в PowerBASIC есть специальный хидер VBAPI32.INC в котором описаны SAFEARRAY API, с помощью которых можно изменять размеры VB-массивов передаваемых в PB-DLL. Вот его кусок:

Код: Выделить всё
Type SAFEARRAYBOUND
  cElements As Dword             ' number of elements
  cLbound As Long                ' LBound of first element
End Type

Type SAFEARRAY
  cDims As Word                  ' Count of dimensions in this array.
  fFeatures As Word              ' Flags used by the SafeArray
  cbElements As Long             ' Size of an element of the array;
                                 ' Does not include size of pointed-to data.
  cLocks As Dword                ' Number of times the array has been
                                 ' locked without corresponding unlock.
  pvData As Dword                ' Pointer to the data.
  rgsabound(3) As SAFEARRAYBOUND ' One bound for each dimension.
End Type

'------------------------------------------------------------------------------

Declare Function SafeArrayGetDim     Lib "OLEAUT32.DLL" Alias "SafeArrayGetDim"     (ByVal psa As Dword) As Dword
Declare Function SafeArrayGetElement Lib "OLEAUT32.DLL" Alias "SafeArrayGetElement" (ByVal psa As Dword, rgIndices As Long, pData As Any) As Long
Declare Function SafeArrayGetLBound  Lib "OLEAUT32.DLL" Alias "SafeArrayGetLBound"  (ByVal psa As Dword, ByVal nDim As Word, lbDim As Long) As Long
Declare Function SafeArrayGetUBound  Lib "OLEAUT32.DLL" Alias "SafeArrayGetUBound"  (ByVal psa As Dword, ByVal nDim As Word, ubDim As Long) As Long
Declare Function SafeArrayRedim      Lib "OLEAUT32.DLL" Alias "SafeArrayRedim"      (ByVal psa As Dword, BoundNew As SAFEARRAYBOUND) As Long
Declare Function SafeArrayUnlock     Lib "OLEAUT32.DLL" Alias "SafeArrayUnlock"     (ByVal psa As Dword) As Long
Declare Function SafeArrayLock       Lib "OLEAUT32.DLL" Alias "SafeArrayLock"       (ByVal psa As Dword) As Long


Т.е. Redim Preserve сводится только к вызову SafeArrayRedim, а не SafeArrayDestroy, SafeArrayAllocDescriptor и SafeArrayAllocData (с новыми размерами массива!) как в случае обычного Redim.
Собственно поэтому и такая разница в скорости работы кода. :)

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Размещение массива в RAM

Сообщение jangle » 15.03.2009 (Вс) 3:25

Хакер писал(а):Объясню.
Есть и другой момент. Этот пример — сферический конь в вакууме.
При ReDim-инге массива для его размещения нужен блок памяти. Положим, что память для массивов выделяется в обычной виндовой куче обычными кучными функциями. Тогда каждый акт редиминга инициирует вызов HeapReAlloc.


Вот тут ты ошибся, возможно так происходит в С++, но в VB это реализовано через Automation API, которые позволяют работать с самоописываемыми одномерными и многомерными массивами. Короче говоря - SAFEARRAY API

След.

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

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14

    TopList  
cron