2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2
 
 Re: Оптимизация временных файлов
Сообщение26.03.2013, 19:54 
Заслуженный участник


06/07/11
5627
кран.набрать.грамота
bin в сообщении #701637 писал(а):
Технический вопрос: а есть ли в рекомендованных здесь СУБД ограничения на размер строки (или на вектор байтов)?
Считайте, что нет. Вот ограничения Oracle 11g - до 128 ТБ (типы BLOB, CLOB и NLOB), у Postgres похуже - 1 GB.

bin в сообщении #701637 писал(а):
Допускаются ли записи, размер которых меняется динамически во время выполнения?
Да.

Joker_vD в сообщении #701747 писал(а):
bin в сообщении #701637 писал(а):
Если я правильно понял, Вы предлагаете писать в индексном файле позицию первого символа каждой строки, а также значения i,j (место элемента в матрице). Т.о. придется постоянно делать выход на нужную позицию файла данных. Диск конечно же не лента, но все же переспрошу: Вы уверены, что так будет быстрее, чем с кучей файлов?

Все это можно делать в одном файле. Особо промышленные СУБД, говорят, вообще под свои нужды целый раздел диска брали и сами ввод-вывод организовывали, но может, и байка это.

Oracle так делает (точнее, может делать и так, и через ОС). Насколько я знаю, они потихонечку от этой практики отказываются и рекомендуют так не делать, но эту сторону оракла я плохо знаю.

P. S. Oracle в "максимальной комплектации" можно использовать в "ознакомительных" целях - если интересно, могу сказать, где скачать (сразу во избежание недоразумений скажу, что скачать можно с официального сайта, официально и бесплатно).

-- 26.03.2013, 21:16 --

bin в сообщении #701637 писал(а):
Про натуральные числа можно утверждать, что они в каждой строке принимают все значения от 0 до $n$.

В оракле необязательно эту последовательность хранить, ее можно сгенерировать в любой момент:
Код:
select rownum - 1
from dual
connect by level <= n+1
В большинстве СУБД есть те или иные способы генерировать последовательности.

-- 26.03.2013, 21:21 --

А такой код
Код:
select listagg(rownum - 1, ', ') within group ()
from dual
connect by level <= n+1
Вернет эту последовательность в виде одной строки через запятую:
0, 1, 2, 3, ... n

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение26.03.2013, 21:26 
Заслуженный участник


06/07/11
5627
кран.набрать.грамота
bin в сообщении #701637 писал(а):
rockclimber в сообщении #701456 писал(а):
Как я понял, вы преобразуете строки в числа
Нет. В модели я преобразовывал числа в строки. В реальной программе более сложная структура данных, которая в настоящий момент описывается дюжиной БНФ. Нет смысла их тут все приводить, приведу одну упрощенную формулу:
Код:
<элемент матрицы>::=<натуральное число>{<разделитель><натуральное число>}
При этом нужно несколько разделителей, например, ",",".","&", а еще и скобки "(",")" (приведенная формула скобки не учитывает), понятно, что речь идет о рекурсивной структуре данных. Про натуральные числа можно утверждать, что они в каждой строке принимают все значения от 0 до $n$ . И тут возникает дополнительный вопрос: как лучше представить такую последовательность чисел с несколькими типами разделителей и скобками? В модели я пошел по самому примитивному пути - взял строки. Но правы те, кто указал, что такое представление не лучшее. Какое лучше на Ваш взгляд? Нужно только отметить, что по мере развития алгоритма приходится корректировать список разделителей и скобок, т.е. формат не полностью устоялся и хотелось бы выбрать достаточно гибкое представление, чтобы не переписывать много кода, если вдруг выяснится, что нужен еще один тип разделителя.
Тут все сильно зависит от того, какие действия предполагает ваш алгоритм. Если вы обрабатываете числа как числа, а храните в виде строк, может вам их и хранить в бинарном виде? ЕМНИП, Delphi должен уметь что-то такое. Там было такое понятие, как "типизированные файлы" - их не пробовали? Что-то вроде такого:
Код:
type
MyRecord = record
  a: integer;
  b: extended;
end;
var
  f: file of MyRecord;
И дальше можно было писать в файл напрямую целую структуру. Но я такое последний раз лет 10 назад делал, плохо помню уже.
Если же делать в БД, я бы предложил создать таблицу такого типа (синтаксис Oracle):
Код:
create table struct(
id number,
matrix_element varchar2(100),
some_number number,
one_more_number number,
parent_id number,
matrix_column number,
matrix row number);

Здесь столбцы id и parent_id нужны для построения иерархии, matrix_element, some_number и one_more_number - ваши элементы, matrix_column и matrix row - координаты в матрице. Тогда выбрать всю иерархическую структуру в одной ячейке матрицы можно например так:
Код:
select *
   from struct
  start with matrix_column = 1 and matrix_row = 2
connect by prior id = parent_id
Такой таблицы с данными под рукой правда нет, так что код написан немного наугад, но в целом идея такая.

bin в сообщении #701637 писал(а):
Но и за неиспользованные возможности приходится платить, и вопрос в том, не окажется ли такая плата слишком высокой для производительности?
Не придется. Это Газпром за недобор газа штрафует, а СУБД в этом отношении попроще :wink:

bin в сообщении #701637 писал(а):
Но наверное никто не сможет ответить мне на вопрос: что лучше в данном случае? сделать маленькое и специализированное или взять уже готовое, большое и универсальное? Придется пробовать: сделать и то и другое, и посмотреть, что будет работать быстрее.
Ну это естественно, никто же даже не знает пока, в чем суть ваших алгоритмов. Могу только сказать - пробуйте, где оптимизировать можно - подскажу по мере своих талантов...

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение26.03.2013, 21:48 
Аватара пользователя


22/09/09

1907
rockclimber в сообщении #701764 писал(а):

bin в сообщении #701637 писал(а):
Про натуральные числа можно утверждать, что они в каждой строке принимают все значения от 0 до $n$.

В оракле необязательно эту последовательность хранить, ее можно сгенерировать в любой момент:
Код:
select rownum - 1
from dual
connect by level <= n+1
В большинстве СУБД есть те или иные способы генерировать последовательности.

-- 26.03.2013, 21:21 --

А такой код
Код:
select listagg(rownum - 1, ', ') within group ()
from dual
connect by level <= n+1
Вернет эту последовательность в виде одной строки через запятую:
0, 1, 2, 3, ... n
Вы меня не поняли. Речь не о какой-то арифметической прогрессии. Последовательностью я называю "<число><разделитель><число>... " Если <число> генерировать генератором случайных чисел, то и в этом случае получим то, что я выше назвал последовательностью, но никакая СУБД в точности такую же сгенерировать не сумеет (с вероятностью близкой, но не равной нулю :D ). При всем произволе random-генератора он может быть устроен так, что все числа от 0 до $n$ (и никакие больше-меньше) найдутся в этой последовательности - в общем случае ее длина сильно больше $n$ . Пример из другой области - последовательность цифр: в числе $\pi$ частота появления цифр 0,...,9 одинакова, но это не позволяет предсказать очередную цифру - ее можно только вычислить...

-- Вт мар 26, 2013 22:17:46 --

rockclimber в сообщении #701804 писал(а):
Если вы обрабатываете числа как числа, а храните в виде строк, может вам их и хранить в бинарном виде?
Я получаю числа фактически из input тривиальным натуральным счетом (как наличные деньги или игральные карты считают - типа: в сдаче оказалось пять треф, две бубны и остальные черви), далее никаких арифметических вычислений с ними не производится. Их можно представить как угодно, но только, если можно, не через extended: имею конечно же право для натурального взять вещественное, но кому это нужно? ;-) Проблема как совместить в последовательности числа с разделителями. Например, если взять 2-х байтовый тип SmallInt (-32768...32767), то числа кодирую как есть от 0 до 32767 - пока для текущих экспериментов этого достаточно, а разделители кодирую отрицательными числами: запятая соответствует -1, точка: -2 и т.д. Но не жирно ли по 2 байта на разделитель?

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение26.03.2013, 22:21 
Аватара пользователя


31/10/08
1244
Цитата:
Не тот случай: в моем случае строки могут полностью совпадать, т.о. при сравнении иногда придется сравнивать все символы. В Delphi, естественно, сравниваются символы до первого несовпадения.

Это обычный прием при сортировки строк, притом любых. 8-)
Вероятность коллизий $1000/2^{64}$. В нашем случае $1000/10^{8}=0.00001$
Само собой разумеется, что при коллизиях проверяются данные целиком.
Если вероятность большая то возьми не 8, а 16 байт.

Цитата:
Т.о. придется постоянно делать выход на нужную позицию файла данных. Диск конечно же не лента, но все же переспрошу: Вы уверены, что так будет быстрее, чем с кучей файлов?

А что для кучи файлов их не будет что-ли? Будет, да ещё и больше. Я уже сказал, что надо кэш создавать и использовать, так что-бы минимизировать обращения.

СУБД я вам порекомендовал потому, что с оптимизировать кода вы явно не справитесь или потратите очень много времени и сил. А вот с СУБД у вас ещё есть шансы сделать это быстро(в обоих смыслах).

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение26.03.2013, 22:35 
Аватара пользователя


22/09/09

1907
rockclimber в сообщении #701804 писал(а):
Ну это естественно, никто же даже не знает пока, в чем суть ваших алгоритмов. Могу только сказать - пробуйте, где оптимизировать можно - подскажу по мере своих талантов...
Оптимизация основного алгоритма - это отдельная тема. В принципе для основной цели работы она и не нужна, т.к. это исследование в области теоретической computer sci. и важно доказать, что алгоритм полиномиальный, а для практики его можно и не приспосабливать. А здесь (в этой подзадаче) мне понадобилась оптимизация, чтобы можно было проводить испытания за приемлемое время. Искать контр-примеры и т.д. - скорость самого алгоритма, когда хватает ОЗУ, меня пока устраивает и делать в основном алгоритме оптимизацию ради чистого спорта не вижу необходимости. Более того, такая оптимизация будет вредна, т.к. затруднит понимание алгоритма/реализации. (Довольно особый случай - полностью непохожий на коммерческое программирование, например.)

-- Вт мар 26, 2013 23:01:06 --

Pavia

(Оффтоп)

Pavia в сообщении #701827 писал(а):
СУБД я вам порекомендовал потому, что с оптимизировать кода вы явно не справитесь или потратите очень много времени и сил.
Можно ли поинтересоваться, почему столь низкое мнение ;-) Сошлюсь на свой опыт оптимизации: несколько лет назад мне нужно было оптимизировать решение большого количества небольших СЛУ. Я пошел двумя путями: стал оптимизировать сам и списался со спецами из Интела по вопросу, как использовать их широко разрекламированные пакеты для данной задачи. Потом послал им свое решение. В итоге они признали, что мое решение для данного типа задач сильно лучше, чем их универсальные :-) Другую оптимизацию вычислительно трудной задачи, высоко важной для компьютерной химии, я опубликовал в J of Math Chem, если интересно, могу дать точную ссылку. Может, Вы считаете, что если кто-то спросил совета, то он ничего не знает/не умеет. Но я не встречал человека, который знал бы все одинаково хорошо. А Вы?

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение27.03.2013, 06:21 
Аватара пользователя


31/10/08
1244
Bin
С чего Вы взяли, что ваш код упирается в жёсткий диск, а не в процессор? Что определяет скорость работы?

По поводу понятности кода. Оптимизированный код, незначит плохо оформленный. Его тоже можно грамотно оформить и он будет понятен.

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение27.03.2013, 08:26 
Заслуженный участник


06/07/11
5627
кран.набрать.грамота
bin в сообщении #701834 писал(а):
В принципе для основной цели работы она и не нужна, т.к. это исследование в области теоретической computer sci. и важно доказать, что алгоритм полиномиальный, а для практики его можно и не приспосабливать.
Я не силен в теории, но мне всегда казалось, что сложность алгоритмов определяется иначе - рассуждениями типа "каждый из n элементов надо сравнить с каждым из остальных n - 1 элементов, поэтому сложность алгоритма - $n^2$". Ну или как-то так, а не через непосредственное время измерения работы компьютера...

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение27.03.2013, 15:38 
Аватара пользователя


22/09/09

1907
rockclimber в сообщении #701920 писал(а):
bin в сообщении #701834 писал(а):
В принципе для основной цели работы она и не нужна, т.к. это исследование в области теоретической computer sci. и важно доказать, что алгоритм полиномиальный, а для практики его можно и не приспосабливать.
Я не силен в теории, но мне всегда казалось, что сложность алгоритмов определяется иначе - рассуждениями типа "каждый из n элементов надо сравнить с каждым из остальных n - 1 элементов, поэтому сложность алгоритма - $n^2$". Ну или как-то так, а не через непосредственное время измерения работы компьютера...
Верно, когда речь идет о теоретической оценке вычислительной сложности алгоритма. Но я поставил вопрос иначе: как оптимизировать ввод/вывод в конкретной программе (не в алгоритме) при заданном алгоритме. Есть некий черный ящик, и здесь мы не обсуждаем, плохой он или хороший, здесь речь про другое: чтобы испытать этот ящик, нужны некоторые вспомогательные действия по вводу/выводу. И нужна не теоретическая оценка, а чисто практическая скорость при разумных затратах. Вполне корректная постановка вопроса.
Pavia в сообщении #701908 писал(а):
По поводу понятности кода. Оптимизированный код, незначит плохо оформленный. Его тоже можно грамотно оформить и он будет понятен.
А какие претензии к оформлению? Что непонятного в приведенном коде? ИМХО там достаточно комментариев.
arseniiv в сообщении #701716 писал(а):
То, какая реализация эффективнее, зависит от того, что вы со своей структурой данных делаете. Строки, конечно, вряд ли подходят уже по такому описанию, но лучше опишите свои данные и операции подробнее.
Что происходит в черном ящике с данными, совершенно другой вопрос. Подойдут любые структуры данных, которыми можно описать последовательности чисел с разделителями нескольких типов. Вопрос в том и только в том: какие структуры данных будут эффективны для обмена с диском?

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение27.03.2013, 18:16 
Заслуженный участник


06/07/11
5627
кран.набрать.грамота
bin в сообщении #702143 писал(а):
Вопрос в том и только в том: какие структуры данных будут эффективны для обмена с диском?

А вы пробовали измерить скорость записи/чтения своего кода (только запись и чтение, без каких-либо вычислений)? Попробуйте сгенерировать кусок мегабайт в сто, а потом записать на диск. А потом сравните с цифрами, которые заявляет производитель диска. И еще, я тут вспомнил, эффективнее всего писать данные блоками, равными блоку файловой системы. Ну и вообще имеет смысл погуглить что-нибудь про WinAPI и оптимизацию...

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение27.03.2013, 18:39 


15/04/12
50
GPU CUDA, OpenCL - ускоряет вычисления

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение27.03.2013, 19:06 
Аватара пользователя


31/10/08
1244
Цитата:
А вы пробовали измерить скорость записи/чтения своего кода (только запись и чтение, без каких-либо вычислений)? Попробуйте сгенерировать кусок мегабайт в сто, а потом записать на диск. А потом сравните с цифрами, которые заявляет производитель диска. И еще, я тут вспомнил, эффективнее всего писать данные блоками, равными блоку файловой системы. Ну и вообще имеет смысл погуглить что-нибудь про WinAPI и оптимизацию...

Пустая трата времени, в этом нет смысла. Луче изучите торию массового обслуживания и очередей.

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение27.03.2013, 19:10 
Админ форума
Аватара пользователя


19/03/10
8952
 !  Pavia, замечание за регулярное неправильное цитирование: в заголовке цитаты отсутствует ссылка на цитируемое сообщение.

Для того чтобы процитировать фрагмент сообщения, выделите его мышкой и нажмите кнопку "Вставка" в цитируемом сообщении.

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение27.03.2013, 19:53 
Заслуженный участник


06/07/11
5627
кран.набрать.грамота
Pavia в сообщении #702234 писал(а):
Пустая трата времени, в этом нет смысла.

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

Pavia в сообщении #702234 писал(а):
Луче изучите торию массового обслуживания и очередей.

Я? Даже пытаться не буду.

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение28.03.2013, 08:29 
Аватара пользователя


31/10/08
1244
rockclimber в сообщении #702274 писал(а):
Нечего сказать? Считаете окружающих недостаточно достойными, чтобы разжевывать азы?

Значит все таки хотите, что бы я АЗЫ разжевал.

Дело в том что в цепочке обработчиков общую скорость определяет самый медленный. Быстрее него вся цепочка работать не сможет.
А у нас такой случай сначала генерируются данные потом записываются в файл.
А если взять средства для замера производительности, то видно что самый медленный обработчик это генерация элемента матрицы.
Т.е. это наш случай, когда не стоит заниматься оптимизацией работы с файлами, а стоит заняться оптимизацией генерации данных.
Как бы вы не оптимизировали работу с файлами, но пока данные генерируются 2 часа. Программа будет работать 2 часа.
Пока мы не с генерируем порцию данные диск будет ждать.

Поэтому я и оптимизировал работу со строками время снизилось до 20 минут. Инструмент показал что операции стали соизмеримы. У уже только тогда я сделал оптимизацию записи.
Время снизилось до 10 минут. Но всё равно, диск работает 10% от своей скорости, так как вынужден ждать процессор.
И надо дальше оптимизировать генерацию данных. Но так как это модель и точный алгоритм генерации будет отличаться, то остановился на этом результате.

Код:
type
TIndexRec=packed record
    FilePos:Int64;
    Size:Int64;
    i,j:Integer;
    end;
TAIndexRec=array [0..0] of TIndexRec;
PAIndexRec=^TAIndexRec;
PIndexRec=^TIndexRec;

type
  TFastString=record
    Size:Integer;
    str:String;
    end;

procedure Add(var fs:TFastString; const s:String); overload;
var LenS:DWord;
begin
LenS:=Length(s);
if fs.Size+LenS>Length(fs.str) then
   begin
   SetLength(fs.str,Length(fs.str)*2);
   end;
move(s[1],fs.str[fs.Size+1],LenS);
fs.Size:=fs.Size+LenS;
end;

procedure FastStringInit(var fs:TFastString; Size:Integer);
begin
fs.Size:=0;
SetLength(fs.str,Size);
end;

function GenStr(i:Integer):String;
var
k:Integer;
s0:String;
fs:TFastString;
begin
        result := '';
        FastStringInit(fs,1000*15);
        for k:=1 to 1000 do
         begin
         s0 := intToStr(k*i); // имитируем вычисления элемента (i, j)
         Add(fs,s0);
         s0:=', ';
         Add(fs,s0)
         end;
        result:=fs.str;
        SetLength(result,Fs.Size);
end;

function IndexRec(FilePos:Int64; Size:Int64; i,j:Integer):TIndexRec;
begin
        Result.FilePos:=FilePos;
        Result.Size:=Size;
        Result.i:=i;
        Result.j:=j;
end;

procedure TForm1.Button2Click(Sender: TObject);
const
nm = 1000; // параметр масштаба
var
i,j : integer;
fp:Int64;
s,path:String;
fs:TFastString;
bdName,iName : string;
fbd,fi : File of byte;
t0,t1 : TDateTime;
IndexCashe:array [1..1000] of TIndexRec;
Size:Integer;
begin
  path := extractFilePath (application.ExeName)+'tmp';
  if not DirectoryExists(path) then
     MkDir (path);
  bdName:=path+'\Matrix.bd';
  iName:=path+'\Matrix.i';
  AssignFile(fbd,bdName);
  AssignFile(fi,iName);
  Rewrite(fbd);
  Rewrite(fi);

  t0 := now;      // стартовое время
  fp:=0;
  FastStringInit(fs,1024*1024);
  for i:=1 to nm do  // для строк i
   begin
    for j:=1 to 1000 do // для столбца j
     begin
        s:=GenStr(i);
        Add(fs,s);
        IndexCashe[j]:=IndexRec(fp,Length(s),i,j);
        Inc(fp,Length(s));
        if fs.Size>$100000 then  // 1 МБайт
           begin
           BlockWrite(fbd,fs.str[1],fs.Size*SizeOf(fs.str[1]));
           fs.Size:=0;
           end;
     end;
     BlockWrite(fi,IndexCashe[1],Length(IndexCashe)*SizeOf(IndexCashe[1]));
     Caption := Format('%d',[i]); // Отображаем прогресс
    end;
  BlockWrite(fbd,fs.str[1],fs.Size*SizeOf(fs.str[1]));
  closeFile(fbd);
  closeFile(fi);
  t1 := now;
  Button2.Caption := 'Done';
  Label1.Caption := ('test finished '+ FloatToStr(SecondSpan(t1,t0))+' sec.');
end;


Что касается сортировки, то я уже описал принципы и закодировал согласно им. Время работы составляет пару минут и упирается в жёсткий диск. Далее только диск менять или весь компьютер. Код не привожу, так как ещё надо доработать, протестировать и оформить должным образом.

Цитата:
И еще, я тут вспомнил, эффективнее всего писать данные блоками, равными блоку файловой системы.

Кратность блока может быть произвольным и почти не влияет на производительность. Т.е он может быть и не кратным.
Кратность была важна 20-40 лет назад, когда памяти было мало. А сейчас ОС кэширует данные и не тратиться на дополнительно чтение.
Вот если вы свой драйвер для жесткого диска пишете. о вам стоит подумать о кэширование. Просто по привычке используют степень кратную 2.

Цитата:
Ну и вообще имеет смысл погуглить что-нибудь про WinAPI и оптимизацию

Не имеет смысла. При больших блоках порядка 256,512 КБайт Write выдаёт 99% от скорости работы жёсткого диска. И доведя процент до 100% вы получите прирост 1.01 раза. Что соизмеримо с погрешностью измерения работы всей системы.
Вот если бы Write выдавал 50% тогда стоило задумываться.

Нет смысла оптимизировать скорость на десятки процентов. Так как эту разницу легко решить заменой комплектующих. А вот если надо ускориться в разы то тут стоит смотреть в сторону алгоритмов, а не WinAPI. Так как переход от O(n^2) к O(n) даст существенный выигрыш. Есть конечно трюки для ускорения в том числе и в разы.

В примере я отказался от Write в пользу BlockWrite только из за того что мне так захотелось, не более того.

 Профиль  
                  
 
 Re: Оптимизация временных файлов
Сообщение04.04.2013, 13:26 
Аватара пользователя


22/09/09

1907
Ok! Спасибо за советы. Отлично работает - получил нужные вычисления за разумное время! Использовал TFileStream, СУБД пока не пробовал.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 30 ]  На страницу Пред.  1, 2

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



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

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


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group