Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.10.2011, 04:38   #1
gusluk
Форумчанин
 
Аватар для gusluk
 
Регистрация: 16.10.2008
Сообщений: 205
По умолчанию Динамический массив

Пишу логер к одному прибору. Т.к. кроме простой записи данных в файл, необходимо выводить график и выполнять некоторые действия с данными, их нужно сохранять в память. Чтобы заранее не занимать много памяти решил сделать массив динамическим. Выделяю массив какой-то длинны, когда он заполняется, копирую данные в другой массив, увеличиваю длину первого, копирую данные в первый, убиваю второй. Естественно это занимает кучу времени, и пока все это происходит, теряется некоторое количество данных.
Как этого избежать? Я понимаю что выделение памяти процесс не быстрый, но может есть способы как решить данную задачу?
gusluk вне форума Ответить с цитированием
Старый 13.10.2011, 07:34   #2
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

А данные какие ?
Просто числа, вещественные, например ?
Тогда всё очень просто. Заведите дин массив, примерно того размера какого нужен график, ну например размер графика 1000 пикселей, вот и сделайте тысячу элементов. Заведите переменную, указывающую текущую позицию сохраняемого элемента(для примера Cur), и переменную указывающую текущий размер массива(len). При получении очередного числа в массив проверяйте превысила ли cur len (cur > len) если да, то записывайте в начало массива, и cur присвойте 0 (для дин массивов индексация с 0), и запись производите в ячейку с индексом cur.
Вывод графика можно сделать тоже достаточно просто, если Вы , конечно уже не используете какой-нибудь Tchart :
берем Timage и наносим на него точку с данными из ячейки Cur (по у, ибо функция от времени, а по x - просто край графика), потом делаем image.canvas.copyrect со сдвигом на 1 пиксель, и далее повторяем цикл приема сохранения и вывода очередного значения

Если понадобится поменять размер массива - функция setlength и переменную len не забыть поменять
phomm вне форума Ответить с цитированием
Старый 13.10.2011, 09:29   #3
gusluk
Форумчанин
 
Аватар для gusluk
 
Регистрация: 16.10.2008
Сообщений: 205
По умолчанию

График нужен полный, т.е. строится не по последнему отрезку данных, а по всему принятому массиву, по этому весь массив приходится хранить в памяти. А сколько именно будет данных заранее не известно, поэтому и было решено массив делать динамическим. Собственно вся проблема в том, что изменение размера массива через функцию setlength происходит очень медленно, и пока это происходит теряется некоторое количество данных приходящих на порт.

Последний раз редактировалось gusluk; 13.10.2011 в 09:38.
gusluk вне форума Ответить с цитированием
Старый 13.10.2011, 09:43   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
Выделяю массив какой-то длинны, когда он заполняется, копирую данные в другой массив, увеличиваю длину первого, копирую данные в первый, убиваю второй. Естественно это занимает кучу времени
А зачем? Просто увеличивайте длину первого без всяких копирований
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 13.10.2011, 09:47   #5
gusluk
Форумчанин
 
Аватар для gusluk
 
Регистрация: 16.10.2008
Сообщений: 205
По умолчанию

А разве можно менять длину массива без потери хранящихся в нем данных?
gusluk вне форума Ответить с цитированием
Старый 13.10.2011, 09:50   #6
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
Сообщение от gusluk Посмотреть сообщение
А разве можно менять длину массива без потери хранящихся в нем данных?
SetLength это без проблем делает
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 13.10.2011, 09:52   #7
gusluk
Форумчанин
 
Аватар для gusluk
 
Регистрация: 16.10.2008
Сообщений: 205
По умолчанию

Аватар, большое спасибо! Был уверен что при использовании SetLength, массив обнуляется, и даже мысли не возникло проверить, а так ли это.
gusluk вне форума Ответить с цитированием
Старый 13.10.2011, 11:28   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Аватар, большое спасибо! Был уверен что при использовании SetLength, массив обнуляется, и даже мысли не возникло проверить, а так ли это.
только, исходя из опыта, всё таки рекомендую выделять память блоками (например, по 100 или по 500 или 1000 элементов - конкретно подберёте сами число). Ну и храните реальный счётчик, сколько ФАКТИЧЕСКИ элементов в массиве.
Дело в том, что операция выделения памяти - это весьма затратная по времени операция.

сравните по быстродействию:
Код:
SetLength(A, 99999999 + 1);
  for i:=0 to High(A) do A[i] := i;
и
Код:
  for i:=0 to  99999999 do begin
     SetLength(A, i+1);
     A[i] := i;
  end;

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

Последний раз редактировалось Serge_Bliznykov; 13.10.2011 в 11:36. Причина: увеличил количество циклов. Иначе вообще не видно разницы... :)
Serge_Bliznykov вне форума Ответить с цитированием
Старый 13.10.2011, 12:27   #9
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

Setlength, емнип, создает новый массив новой длины, копирует туда из старого, и меняет ссылку со старого на новый массив. Чем меньше сетленсов, тем лучше для производительности

Последний раз редактировалось phomm; 13.10.2011 в 12:37.
phomm вне форума Ответить с цитированием
Старый 13.10.2011, 15:27   #10
gusluk
Форумчанин
 
Аватар для gusluk
 
Регистрация: 16.10.2008
Сообщений: 205
По умолчанию

Думаю что выделение памяти по одному не есть гуд. Сейчас сначала выделяю память на 1000 элементов, при заполнении массива увеличиваю его длину но половину.
gusluk вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Динамический массив Си GoRdoN 17 Помощь студентам 9 25.01.2013 15:23
Динамический массив botaniQQQ Паскаль, Turbo Pascal, PascalABC.NET 3 27.06.2011 08:44
Динамический массив, массив указателей alexalisa Паскаль, Turbo Pascal, PascalABC.NET 4 22.04.2011 21:33
Динамический массив - или всё таки не динамический? vedro-compota Общие вопросы C/C++ 30 10.12.2010 23:22
Динамический массив Porsche Общие вопросы C/C++ 5 26.05.2010 08:04