Форум: "Основная";
Текущий архив: 2005.08.14;
Скачать: [xml.tar.bz2];
ВнизХранение данных больших размеров Найти похожие ветки
← →
olorint © (2005-07-23 14:33) [0]В программе необходимо хранить данные больших размеров. Точнее массив записей размером в 16 млн. ячеек. Типы в записе: byte и word. Массив в памяти занимает 400mb. Думал записать его в файл и работать ч/з файл, но ч/з некоторое время программа выдает ошибку переполнение стека. Глобальных переменных в программе нет. Все локальные освобождаются после использования.
Как ускорить работу Delphi с такими данными.
← →
evvcom © (2005-07-23 14:59) [1]
> но ч/з некоторое время программа выдает ошибку переполнение
> стека. Все локальные
> освобождаются после использования.
Ты такой массив в стеке хранишь? Убери. Используй динамический массив, и стек будет в порядке.
← →
palva © (2005-07-23 15:06) [2]1. По-моему надо работать через файл.
2. >Как ускорить работу Delphi с такими данными
Во-первых, нужно устранить ошибку, которая приводит к переполнению стека. А как ускорить - это во многом зависит от того, какая работа с данными требуется. Возможно, получится ускорение от перехода с файла на базу данных, например, Access
← →
Anatoly Podgoretsky © (2005-07-23 15:10) [3]olorint © (23.07.05 14:33)
Массив в памяти занимает 16/32 мегабайта
← →
olorint © (2005-07-23 20:10) [4]массив - используется как хранилище данных, т.е. при начале работы программы он инициализируется на основе исходных данных, а потом происходит чтение ячеек. Использовать БД нельзя, т.к. по ТЗ не предусмотрено.
To Podgoretsky
Насчет 32 Мб не согласен. Массив записанный в файл занимает 400 Мб. Тоже самое и при хранении его в памяти.
evvcom
Насчет динамического не пробовал. Сейчас посмотрим.
← →
vrem (2005-07-23 20:32) [5]16 млн *(1+2) = 48 млн байт = 45,776 мегабайт
← →
begin...end © (2005-07-23 20:37) [6]> Anatoly Podgoretsky © (23.07.05 15:10) [3]
> vrem (23.07.05 20:32) [5]
В [0] не указано количество полей типа Byte или Word. Возможно также, что это переопределённые типы.
← →
tesseract © (2005-07-23 20:40) [7]Процесс в Windows Nt/XP может адресовать до 4GB виртуальной памяти.
>>>Насчет 32 Мб не согласен. Массив записанный в файл занимает 400 Мб. Тоже самое и при хранении его в памяти.
А оно тебе надо ? Массив в памяти запросто займёт больше места. Как правило они так и делают - за счёт служебной информации и тд и тп.
>> byte и word это если только у тебя Packed Record. Компилер дельфей оптимизируй код под пни выполняет 32-битное выравнивание - все целочисленные числа приводяться под int32.
>> Ты такой массив в стеке хранишь?
ЁЁЁЁЁЁЁЁЁЁ причём здесь массив и SteckOverflow ?????? а тем более динамический массив который вообще памяти кушает тремя ложками.
StackOverflow связан с вызовами функций - скорее всего проблема в рекурсивном вызове некотрых функций.
>> ячеек. Использовать БД нельзя, т.к. по ТЗ не предусмотрено.
А ты предусмотри.
← →
begin...end © (2005-07-23 20:43) [8]> tesseract © (23.07.05 20:40) [7]
> причём здесь массив и SteckOverflow
Притом, что локальные переменные размещаются в стеке.
> а тем более динамический массив который вообще памяти
> кушает тремя ложками
Всё, что он кушает, он кушает из кучи, а не из стека.
← →
Anatoly Podgoretsky © (2005-07-23 20:46) [9]olorint © (23.07.05 20:10) [4]
Ты не волнуйся, но у тебя в программе ошибка.
← →
tesseract © (2005-07-23 20:51) [10]>>Притом, что локальные переменные размещаются в стеке.
И ещё перед каждой операцией с любой переменной вставляется скрытый try .. except.
>> Всё, что он кушает, он кушает из кучи, а не из стека.
системный стек вызова и данная ошибка, как правило, сильно взаимосвязаны.
← →
palva © (2005-07-23 20:58) [11]Можно работать, разместив массив в памяти, но тогда скорее всего будет подкачка памяти с диска. Алгоритм подкачки анализирует статистику обращений к массиву и располагает малоиспользуемые в настоящий момент фрагменты на диске. Как правило у программиста имеется возможность, зная алгоритм задачи, организовать подкачку самому более эффективно. Кроме того он может изменить сам алгоритм задачи (скажем обрабатывать массив частями) с тем чтобы подкачку (ручную) можно было легче организовать.
Такие соображения...
← →
begin...end © (2005-07-23 21:01) [12]> tesseract © (23.07.05 20:51) [10]
> И ещё перед каждой операцией с любой переменной
> вставляется скрытый try .. except.
Вставки чего-то перед каждой операцией с любой переменной я не замечал. Кстати, Вы это к чему? Вы спросили, какая связь между массивом и переполнением стека. Я ответил.
← →
tesseract © (2005-07-23 21:11) [13]to palva >>> Как правило в данном случае приходится при любой олперации перелопачивать весь массив те конкретный загруз всех страниц в память. ТЕ надо не грузить его весь в память а обходиться малыми средствами.
to olorint>> Некоторый выход все данные с диска читать необязательно record имеет устаканенный формат? тогда размер его фиксирован, следовательно можно сбросить данные на диск и искать нужные данные Read() с установленным размером блока в Reset в размер записи.
← →
tesseract © (2005-07-23 21:16) [14]>>to begin..end
Массив сам по себе размешается в куче, а не в стеке - стек совершенно другой тип данных SteckOverflow- показатель того что система не может сохранить все данные текущей функции перед вызовом другой. Т.Е. Какое это отношение имеет к данным?
try .. except реально вставляется перед любой операцией с не константами кроме операций с указателями. Т.Е реально можно получить либо SteсkOverflow либо дельфи выдаст AccessViolation.
← →
begin...end © (2005-07-23 21:31) [15]> tesseract © (23.07.05 21:16) [14]
> Массив сам по себе размешается в куче, а не в стеке
Вас обманули. Вот простой пример:function F: Integer;
var
A: array [1..5] of Integer; <-- Статический массив, являющийся локальной переменной
begin
Result := A[1]
end.
Вызываем эту функцию в коде и смотрим в окно CPU. Функция начинается вот с чего:83C4EC add esp,-$14
Это -- уменьшение указателя вершины стека на $14 = 20, т.е. выделение в СТЕКЕ памяти под массив A размером 20 байт.
> try .. except реально вставляется перед любой
> операцией с не константами кроме операций с
> указателями.
Ну-ну.
← →
palva © (2005-07-23 22:24) [16]> приходится при любой операции перелопачивать весь массив те конкретный загруз всех страниц в память
Тяжелый случай. Может быть можно переупорядочить массив так, чтобы перелопачивание шло более-менее последовательно? Скажем, если массив содержит представление большого графа, то можно попробовать упорядочить вершины.
В любом случае надо ставить на машину как можно большую память.
← →
olorint © (2005-07-27 01:27) [17]Народ, большое всем спасибо за советы.
Конечно все проблемы можно решить добавлением новой планки памяти, но это не интересно.
Так что результат такой:динамическое выделение памяти не дает особых результатов. А дальше как ни странно банальные истины, которые каждый знает но мало ими пользуется (по себе сужу).
Насчет переполнения стека:
можно использовать и динамическую память, но сначала стоило проверить возможные(теоретические значения переменных), и изменить тип. Так например Integer сменил на Word а это уже 2 байта. и так далее по мелочам.
Практические испытания показали на моем компьютере, размер переменных (локальных), приходящихся на одну процедуру не может превышать 25 Мб. Можно перевести переменные в динамические или объявить их глобальными(дико, но работает), либо использовать файл для их хранения на диске.
Сравнение времени для обработки массива на 29 млн записей формата 3 поля Word 3 поля Byte, показало преимущество ипользования файла а не динамической памяти. Время 40-60 сек.
Спасибо всем за помощь, некоторые идеи помогли решить дальнейшие проблемы.
Вопрос закрыт.
← →
Slym © (2005-07-27 12:02) [18]MemoryMappedFile - компромис файла-памяти
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.08.14;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.012 c