Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.03.02;
Скачать: [xml.tar.bz2];

Вниз

Чтение из 2-х гигового лога...   Найти похожие ветки 

 
palva ©   (2008-02-05 13:14) [40]


> Игорь Шевченко ©   (05.02.08 12:24) [37]
> palva ©   (05.02.08 12:04) [31]
> У меня просьба - тесты местами поменяй ?

У меня обед кончился экспериментировать.
Если вы хотите, чтобы до нас дошла какая-то известная вам высокая истина, то вы выбрали не тот метод. Обсудите условия эксперимента, объясните подноготную, подготовьте и прогоните правильные с вашей точки зрения тесты выложите результаты - в общем, сделайте сами все то, что нам советуете. А ваш опыт и знания мы и так уважаем.

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

> Slym ©   (05.02.08 12:18) [33]
> palva ©   (05.02.08 12:04) [31]
> плохой тест...

Ну это возможно. Напишите хороший тест или модифицируйте нужным образом мой. Возьмите к примеру второй мой тест и поменяйте коэффициент блокирования. Длину блока сделайте 50 и выложите результат. А я сейчас не могу этим заниматься.


 
Игорь Шевченко ©   (2008-02-05 13:16) [41]

palva ©   (05.02.08 13:14) [40]

Истина очень простая - после первого теста данные находятся в кэше Windows и во втором тесте они читаются несколько быстрее.


 
clickmaker ©   (2008-02-05 13:17) [42]


> то чтение большими блоками, если говорить о программе на
> паскале, в разы ускоряет процесс

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


 
хам   (2008-02-05 13:18) [43]

> [40] palva ©   (05.02.08 13:14)
> Если вы хотите, чтобы до нас дошла какая-то известная вам
> высокая истина

Эта истина известна всем: виндовс кеширует и буферизирует чтение с диска.


 
palva ©   (2008-02-05 13:44) [44]


> Игорь Шевченко ©   (05.02.08 13:16) [41]
> palva ©   (05.02.08 13:14) [40]
> Истина очень простая - после первого теста данные находятся
> в кэше Windows и во втором тесте они читаются несколько
> быстрее.

В теории так и должно быть. Я потратил еще 5 минут, чтобы попробовать. Перед каждым тестом перезагружал машину (всю).
Второй тест:
13:23:12
13:23:24
Потом перезагрузился и запустил первый тест:
13:26.15
13:26.43


 
palva ©   (2008-02-05 13:46) [45]


> хам   (05.02.08 13:18) [43]

Кстати, какая у вас версия делфи. Я делал на 7.0.


 
хам   (2008-02-05 13:49) [46]

> [45] palva ©   (05.02.08 13:46)
> Кстати, какая у вас версия делфи. Я делал на 7.0.

Я тоже сделал на д7, но см [36].


 
хам   (2008-02-05 13:50) [47]

упраздил, конечно же, из обоих тестов :)


 
palva ©   (2008-02-05 13:56) [48]


> хам   (05.02.08 13:49) [46]
> но см [36].

Я смотрю ваше [34] и удивляюсь.


 
Anatoly Podgoretsky ©   (2008-02-05 14:44) [49]

Кроме указаных методов, серьезное ускорение можно получить при переходе на Юникод функции.
Ну и конечно MMF, но надо подумать над алгоритмами, что бы не получить обратное.


 
clickmaker ©   (2008-02-05 14:57) [50]

если запросить у MapViewOfFile сразу весь большой файл, можно получить отлуп по причине недостатка памяти.
Так что, там тоже блоками надо


 
DVM ©   (2008-02-05 15:11) [51]

MMF - не панацея. Распространенное заблуждение, что MMF поможет ускорить поиск в огромном файле.


 
хам   (2008-02-05 15:15) [52]

Что есть MMF то?


 
DVM ©   (2008-02-05 15:17) [53]


> хам   (05.02.08 15:15) [52]

Файлы отображенные в память


 
хам   (2008-02-05 15:19) [54]

Ну ясно. И как они могут увеличить скорость чтения с диска?


 
DVM ©   (2008-02-05 15:20) [55]


> И как они могут увеличить скорость чтения с диска?

Чтения с диска  - никак.


 
ketmar ©   (2008-02-05 15:30) [56]

>[51] DVM©(05.02.08 15:11)
таки поможет.


 
Игорь Шевченко ©   (2008-02-05 15:32) [57]

Мои исследования: (Сразу скажу, что palva прав)

program ReadTest;

{$APPTYPE CONSOLE}

uses
 SysUtils,
 Main in "Main.pas";

begin
 if ParamCount >= 1 then
   if UpperCase(Copy(ParamStr(1),1,2)) = "-B" then
     ReadBlock
   else
     ReadLine;
end.


unit Main;

interface

procedure ReadBlock;
procedure ReadLine;

implementation
uses
 SysUtils, Windows;

var
 StartTime: TDateTime;

type
 IO_COUNTERS = packed record
   ReadOperationCount: LARGE_INTEGER;
   WriteOperationCount: LARGE_INTEGER;
   OtherOperationCount: LARGE_INTEGER;
   ReadTransferCount: LARGE_INTEGER;
   WriteTransferCount: LARGE_INTEGER;
   OtherTransferCount: LARGE_INTEGER;
 end;
 PIO_COUNTERS = ^IO_COUNTERS;

function GetProcessIoCounters(Process: THandle; Ios: PIO_COUNTERS): Boolean;
 stdcall; external "Kernel32.dll";

procedure PrintIos;
var
 Ios: IO_COUNTERS;
begin
 if GetProcessIoCounters(GetCurrentProcess(), @Ios) then
   writeln(IntToStr(Ios.ReadOperationCount.QuadPart), " read IOs ",
     IntToStr(Ios.ReadTransferCount.QuadPart), " bytes read");
end;

procedure ReadBlock;
var
fo: file;
i, j: Integer;
s: string;
begin
 StartTime := Now;
 Assign(fo, "c:\files\bigtest.txt");
Reset(fo, 50000);
SetLength(s, 50000);
I := 0;
while not Eof(fo) do begin
  BlockRead(fo, s[1], 1);
  for j := 1 to Length(S) do
    if s[J] = " " then
      Inc(I);
end;
closefile(fo);
 WriteLn("Elapsed: "+FormatDateTime("hh:nn:ss", now-StartTime), " ", i);
 printios;
end;

procedure ReadLine;
var
fo: textfile;
i, j: Integer;
s: string;
begin
 StartTime := Now;
 Assign(fo, "c:\files\bigtest.txt");
 Reset(fo);
 I := 0;
 while not eof(fo) do begin
   ReadLn(fo, s);
   for j := 1 to Length(S) do
     if s[J] = " " then
       Inc(I);
 end;
 closefile(fo);
 WriteLn("Elapsed: "+FormatDateTime("hh:nn:ss", now-StartTime), " ", i);
 printios;
end;

end.


Результат построчного чтения:

Elapsed: 00:00:34 95103772 пробелов
8351152 read IOs 1069000094 bytes read

Результат поблочного чтения:

Elapsed: 00:00:04 95099921
21379 read IOs 1068952958 bytes read

Видно, что поблочное чтение читает не весь файл, но разницей в данном случае можно пренебречь.
Файл, соответственно, гигабайтный


 
хам   (2008-02-05 15:36) [58]

Игорь, а какая версия дельфи?


 
DVM ©   (2008-02-05 15:36) [59]


> ketmar ©   (05.02.08 15:30) [56]


> таки поможет.

Как?


 
DVM ©   (2008-02-05 15:38) [60]


> Игорь Шевченко ©   (05.02.08 15:32) [57]

А я и не сомневался.


 
Игорь Шевченко ©   (2008-02-05 15:42) [61]

хам   (05.02.08 15:36) [58]

2006

Соответственно, сделан еще один тест, через отображение в память

Elapsed: 00:00:04 95103772
1 read IOs 52958 bytes read

Читается весь файл, операции ввода-вывода здесь совершенно не учитываются, так что строчка просто скопирована :)

Код:

program ReadTest;

{$APPTYPE CONSOLE}

uses
 SysUtils,
 Main in "Main.pas";

begin
 if ParamCount >= 1 then
   if UpperCase(Copy(ParamStr(1),1,2)) = "-B" then
     ReadBlock
   else if UpperCase(Copy(ParamStr(1),1,2)) = "-M" then
     ReadMap
   else
     ReadLine;
end.


unit Main;

interface

procedure ReadBlock;
procedure ReadLine;
procedure ReadMap;

implementation
uses
 SysUtils, Windows, HsFileMapper;

var
 StartTime: TDateTime;

type
 IO_COUNTERS = packed record
   ReadOperationCount: LARGE_INTEGER;
   WriteOperationCount: LARGE_INTEGER;
   OtherOperationCount: LARGE_INTEGER;
   ReadTransferCount: LARGE_INTEGER;
   WriteTransferCount: LARGE_INTEGER;
   OtherTransferCount: LARGE_INTEGER;
 end;
 PIO_COUNTERS = ^IO_COUNTERS;

function GetProcessIoCounters(Process: THandle; Ios: PIO_COUNTERS): Boolean;
 stdcall; external "Kernel32.dll";

procedure PrintIos;
var
 Ios: IO_COUNTERS;
begin
 if GetProcessIoCounters(GetCurrentProcess(), @Ios) then
   writeln(IntToStr(Ios.ReadOperationCount.QuadPart), " read IOs ",
     IntToStr(Ios.ReadTransferCount.QuadPart), " bytes read");
end;

procedure ReadBlock;
var
fo: file;
i, j: Integer;
s: string;
begin
 StartTime := Now;
 Assign(fo, "c:\files\bigtest.txt");
Reset(fo, 50000);
SetLength(s, 50000);
I := 0;
while not Eof(fo) do begin
  BlockRead(fo, s[1], 1);
  for j := 1 to Length(S) do
    if s[J] = " " then
      Inc(I);
end;
closefile(fo);
 WriteLn("Elapsed: "+FormatDateTime("hh:nn:ss", now-StartTime), " ", i);
 printios;
end;

procedure ReadLine;
var
fo: textfile;
i, j: Integer;
s: string;
begin
 StartTime := Now;
 Assign(fo, "c:\files\bigtest.txt");
 Reset(fo);
 I := 0;
 while not eof(fo) do begin
   ReadLn(fo, s);
   for j := 1 to Length(S) do
     if s[J] = " " then
       Inc(I);
 end;
 closefile(fo);
 WriteLn("Elapsed: "+FormatDateTime("hh:nn:ss", now-StartTime), " ", i);
 printios;
end;

procedure ReadMap;
var
 Mapper: THSFileMapper;
 P: PChar;
 I, J: Integer;
begin
 StartTime := Now;
 Mapper := THSFileMapper.Create("c:\files\bigtest.txt");
 try
 P := Mapper.Map;
 I := 0;
 for J := 0 to Mapper.FileSize - 1 do
 begin
   if P^ = " " then
     Inc(I);
   Inc(P);
 end;
 finally
   Mapper.Free;
 end;
 WriteLn("Elapsed: "+FormatDateTime("hh:nn:ss", now-StartTime), " ", i);
 printios;
end;

end.


{
  Модуль: HSFileMapper

  Описание: Класс, обеспечиващий создание файла, проецируемого в память

  Автор: Игорь Шевченко

  Дата создания: 07.02.2003

  История изменений:
}
unit HsFileMapper;
{$I HsCommon.Inc}
{$IFDEF _D6}
{$WARN SYMBOL_PLATFORM OFF}
{$WARN SYMBOL_DEPRECATED OFF}
{$ENDIF}

interface
uses
 Windows;

type
 THSFileMapper = class
 private
   FFileHandle: THandle;
   FFileSize: DWORD;
   FMap: PChar;
   FFileName: string;
   function GetEndMap: PChar;
 public
   constructor Create (const AFileName: string);
   destructor  Destroy; override;
   property Map: PChar read FMap;
   property EndMap: PChar read GetEndMap;
   property FileSize: DWORD read FFileSize;
   property FileName: string read FFileName;
 end;

implementation
uses
 SysUtils;

{ THSFileMapper }

constructor THSFileMapper.Create(const AFileName: string);
var
 SizeHighPart: DWORD;
 FileMapping: THandle;
begin
 FFileName := AFileName;
 FFileHandle := CreateFile (PChar(AFileName), GENERIC_READ,
   FILE_SHARE_READ or FILE_SHARE_WRITE,
   nil, OPEN_EXISTING, 0, 0);
 if FFileHandle = INVALID_HANDLE_VALUE then
   RaiseLastWin32Error;
 FFileSize := GetFileSize(FFileHandle, @SizeHighPart);
 FileMapping := CreateFileMapping (FFileHandle, nil, PAGE_READONLY, 0, 0, nil );
 if FileMapping = 0 then
   RaiseLastWin32Error;
 FMap := MapViewOfFile (FileMapping, FILE_MAP_READ, 0, 0, 0 );
 CloseHandle (FileMapping);
 if not Assigned(FMap) then
   RaiseLastWin32Error;
end;

destructor THSFileMapper.Destroy;
begin
 if Assigned(FMap) then
   UnmapViewOfFile (FMap);
 if FFileHandle <> INVALID_HANDLE_VALUE then
   CloseHandle (FFileHandle);
 inherited;
end;

function THSFileMapper.GetEndMap: PChar;
begin
 Result := FMap + FFileSize;
end;

end.


Как видно, способ с отображением файла наиболее прост в коде :)


 
хам   (2008-02-05 15:48) [62]

> [61] Игорь Шевченко ©   (05.02.08 15:42)
> Как видно, способ с отображением файла наиболее прост в коде :)

Ага, пока Память приложения + размер файла < 2 гб.


 
ketmar ©   (2008-02-05 15:51) [63]

>[59] DVM©(05.02.08 15:36)
>Как?

убираются лишние гоняния данных по памяти.


 
Игорь Шевченко ©   (2008-02-05 15:52) [64]

хам   (05.02.08 15:48) [62]

Безусловно. Но цель ставилась оценить скорость чтения.


 
хам   (2008-02-05 15:58) [65]

> [64] Игорь Шевченко ©   (05.02.08 15:52)
> Но цель ставилась оценить скорость чтения.

Да я знаю :)


 
DVM ©   (2008-02-05 16:02) [66]


> ketmar ©   (05.02.08 15:51) [63]

Но на скорость чтения именно с диска это же не влияет. В любом случае читаем.


 
хам   (2008-02-05 16:02) [67]

> [63] ketmar ©   (05.02.08 15:51)
> убираются лишние гоняния данных по памяти.

Это все равно ничтожно мало по сравению с временем чтения диска, с ReadLn дело в чем-то другом, не знаю уж, как она изнутри сделана.


 
Игорь Шевченко ©   (2008-02-05 16:07) [68]

хам   (05.02.08 16:02) [67]


> с ReadLn дело в чем-то другом, не знаю уж, как она изнутри
> сделана.


Операций чтения (запросов к тому самому менеджеру кэша) в случае ReadLn гораздо больше. Мне самому стала интересна статистика именно ввода вывода


 
хам   (2008-02-05 16:10) [69]

> [68] Игорь Шевченко ©   (05.02.08 16:07)
> Операций чтения (запросов к тому самому менеджеру кэша)
> в случае ReadLn гораздо больше.

Ну не побайтово же она должна читать, в конце то концов :)


 
ANB   (2008-02-05 16:14) [70]


> Ну не побайтово же она должна читать, в конце то концов
> :)

Похоже, именно побайтово она и читает.


 
Игорь Шевченко ©   (2008-02-05 16:28) [71]

хам   (05.02.08 16:10) [69]


> Ну не побайтово же она должна читать, в конце то концов
> :)


По 128 байт она читает. То есть, на каждые 128 байт вызывается ReadFileA
Если воспользоваться калькулятором, то из
8351159 read IOs 1069023496 bytes read

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


 
Leonid Troyanovsky ©   (2008-02-05 19:37) [72]


> ketmar ©   (05.02.08 15:30) [56]

> таки поможет.

http://groups.google.com/group/fido7.su.win32.prog/msg/14bb69b4dec1da1a?dmode=source&output=gplain

http://groups.google.com/group/fido7.su.win32.prog/msg/e4edc3fb35401f38?dmode=source&output=gplain

Кодировка KOI8-R

--
Regards, LVT.


 
palva ©   (2008-02-05 21:44) [73]

Попробовал компилятор Borland С++ 5.5. Только уже дома, на другом компьютере. Тесты дают одно и то же время - 9 секунд. Перезагрузку между тестами не делал.

#include <stdio.h>
#include <string.h>
#include <time>
FILE *fi;
int i;
char buf[51];
time_t t;
main() {
 t = time(0);
 buf[50] = 0;
 fi = fopen("bigtest.txt", "rb");
 for(i=0; i < 10000000; ++i) {
   fread(buf, 50, 1, fi);
   if(memchr(buf,  "*", 50)) printf("%c\n", buf[0]);
 }
 fclose(fi);
 printf("%d\n", time(0) - t); // выдает 9
}


#include <stdio.h>
#include <string.h>
#include <time>
FILE *fi;
int i;
time_t t;
char buf[50001];
main() {
 t = time(0);
 buf[50000] = 0;
 fi = fopen("bigtest.txt", "rb");
 for(i=0; i < 10000; ++i) {
   fread(buf, 50000, 1, fi);
   if(memchr(buf,  "*", 50000)) printf("%c\n", buf[0]);
 }
 fclose(fi);
 printf("%d\n", time(0) - t); // выдает 9
}



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2008.03.02;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.62 MB
Время: 0.046 c
15-1201595132
needhelp
2008-01-29 11:25
2008.03.02
проюлема с HDD


2-1202111662
MZG
2008-02-04 10:54
2008.03.02
Не понятно в Tree View


15-1201507817
Dennis I. Komarov
2008-01-28 11:10
2008.03.02
Asus P750 vs GloFish x800


15-1201424991
Kostafey
2008-01-27 12:09
2008.03.02
С днем рождения ! 27 января


8-1174833897
San ciz
2007-03-25 18:44
2008.03.02
Запись видео с экрана





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский