Форум: "Потрепаться";
Текущий архив: 2002.07.25;
Скачать: [xml.tar.bz2];
ВнизПочему такая разница в скорости обработки?!!! Найти похожие ветки
← →
edd (2002-06-25 14:10) [0]Решил попробовать написать одну програмку для dbf на Delphi, но сперва решил сравнить скорость обработки. Использовал Halcyon.
Исходные данные:
DBF файл объемом 85М. Используем сканирование базы и печать одного из полей на экран.
Имеем:
В FoxPro2.5 время 13 сек.
В Delphi6+Halcyon6.94 время 1 мин 53 сек.
ПОЧЕМУ?!!!
← →
sniknik (2002-06-25 14:46) [1]Потомучто!!!!!
самый грамотный ответ на ПОЧЕМУ?!!!
и глупости разные
FoxPro2.5-дос вывод в текстовом режиме
Delphi6-win вывод в графике
FoxPro2.5- для баз
Delphi6- универсальный (а значит может все но чуть хуже чем спец.язык)
FoxPro2.5- думает за тебя как к записи обращатся
Delphi6- нужно самому (небось через FieldByName запись читаеш?)
......
и самое правильное действие для ускорения, необходимо поменять прокладку! (между монитором и клавиатурой :-)
← →
edd (2002-06-25 18:11) [2]Самое умное в ответе - это последняя фраза.
Delphi меня разочаровал - разница в 10 РАЗ!!!
Хотя наверно причина в Halcyon, который написан на Delphi.
Может кто посоветует, как ускорить процесс.
Кто нибудь замерял разницу при использование BDE или ADO.
Вот исходник на Delphi:
program FileList;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils, gs6_Shel;
var
MyTable: TgsDBFTable;
begin
MyTable := TgsDBFTable.Create("Master.DBF","",true,true); {ReadWrite and Shared}
MyTable.First;
while not MyTable.EOF do
begin
Writeln(MyTable.StringGet("SYMBOL"));
MyTable.Next;
end;
MyTable.Free;
end;
end.
Вот Fox:
SET ECHO OFF
SET TALK OFF
use master
do while !eof()
? symbol
skip
enddo
quit
← →
edd (2002-06-25 18:14) [3]Более того!!!! Без вывода на экран разница в скорости не меняется!!!
← →
sniknik (2002-06-25 19:00) [4]всетаки по имени
попробуй так гарантировано будет быстрее
хотя скорости Fox-а не добьешся факт.
program FileList;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils, gs6_Shel;
var
MyTable: TgsDBFTable;
I: Integer;
begin
MyTable := TgsDBFTable.Create("Master.DBF","",true,true); {ReadWrite and Shared}
I:= MyTable.FieldByName("SYMBOL").Index;
MyTable.First;
while not MyTable.EOF do
begin
Writeln(MyTable.Fields[I].AsString);
MyTable.Next;
end;
MyTable.Free;
end;
end.
← →
sniknik (2002-06-25 19:20) [5]Сорру не обратил внимание на то что используеш.
program Project3;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils, gs6_Shel;
var
MyTable: TgsDBFTable;
I: Integer;
begin
MyTable := TgsDBFTable.Create("D:\CASHSAIL.DBF","",true,true); {ReadWrite and Shared}
I:= MyTable.FieldNo("SYMBOL");
MyTable.First;
while not MyTable.EOF do
begin
Writeln(MyTable.StringGetN(I));
MyTable.Next;
end;
MyTable.Free;
end.
← →
sniknik (2002-06-25 19:34) [6]edd © (25.06.02 18:14)
Более того!!!! Без вывода на экран разница в скорости не меняется!!!
вот эт ты зря очень меняется. позволил себе чуть изменить код для теста, так разница с выводом и без на таблице 3200 поз. в 2 сек. (без вывода он и сек. не показывает, 0) у тебя это более существенно будет.
program Project3;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils, gs6_Shel;
var
MyTable: TgsDBFTable;
I: Integer;
BegTime: Tdatetime;
St: string;
begin
MyTable := TgsDBFTable.Create("D:\CASHSAIL.DBF","",true,true); {ReadWrite and Shared}
I:= MyTable.FieldNo("CARDARTICU");
MyTable.First;
BegTime:= Time;
while not MyTable.EOF do
begin
// Writeln(MyTable.StringGetN(I));
St:= MyTable.StringGetN(I);
MyTable.Next;
end;
Writeln(St);
Writeln(TimeToStr(BegTime));
Writeln(TimeToStr(Time));
readln;
MyTable.Free;
end.
← →
edd (2002-06-25 20:48) [7]За такой ответ спасибо, сейчас буду разбираться.
← →
Viewer (2002-06-25 21:47) [8]Вот результаты небольшого эксперимента по доступу к данным
Использовались форматы таблиц
Paradox 7
DBase 4
DBISAM
Использовались движки
BDE (db, dbf)
DBISAM (dat)
tsvDBF (dbf) - собственный движок доступа к файлам формата Dbase
Все таблицы имели поля
ID: integer;
NAME: char(64)
Индексы: (собственно они здесь не нужны, но для идентичности условий)
по ID первичный
по NAME вторичный
Число записей 100 тыс
Замерялось время сканирования, чтения записи по полю NAME через индекс поля и присваивание edName.Text
with Table do begin
while not EOF do begin
edName.Text := Fields[2].AsString;
// edName.Text := Fields[2]; // для tsvDBF
Next;
end;
end;
Вот результаты в сек. и снижение производительности в % по отн. к лучшему tsvDBF
tsvDBF__________ 5.7
DBISAM__________ 5.8___ 2%
BDE Paradox_____ 6.0___ 5%
BDE Dbase_______ 6.4___12%
Это - только чтение в переменную string
tsvDBF__________ 1.3
DBISAM__________ 1.4
BDE Paradox_____ 1.6
BDE Dbase_______ 1.9
Собственно, эти два результата и есть отношение скоростей безиндексного доступа для движков и форматов.
А это без чтения, только Next
BDE Dbase_______ 0.8
BDE Paradox_____ 0.9
DBISAM__________ 1.1
tsvDBF__________ 1.1
Размеры файлов Mbyte
db___ 7.0
dbf__ 7.1
dat__ 7.5
Занятные результаты ?
← →
Viewer (2002-06-25 21:53) [9]Для справки переход от обращения к полю по имени на обращение
через индекс увеличивает скорость доступа на 3% при 2-х полях.
При большом числе полей это более сещественно.
← →
edd (2002-06-26 14:16) [10]Провел тестирование, вот результаты.
Объем базы 85М (352781 записей).
Fox2.5dos:
Scan and print
16:05:41
16:05:54
Scan
16:05:54
16:06:01
Scan and replace
16:06:01
16:06:12
Replace all
16:06:12
16:06:23
Locate
16:06:24
16:06:31
Delphi6+Halcyon:
Scan and print
15:58:30
16:00:31
Scan
16:00:31
16:00:45
Scan and replace
16:00:45
16:02:12
Search
16:02:12
16:02:28
Исходники.
------------
set echo off
set talk off
use test
BegTime=time()
do while !eof()
? username
skip
enddo
EndTime=time()
? "Scan and print"
? BegTime
? EndTime
use
use test
BegTime=time()
do while !eof()
skip
enddo
EndTime=time()
? "Scan"
? BegTime
? EndTime
use
use test
BegTime=time()
do while !eof()
replace username with alltrim(str(recno()))
skip
enddo
EndTime=time()
? "Scan and replace"
? BegTime
? EndTime
use
use test
BegTime=time()
replace all username with alltrim(str(recno()))
EndTime=time()
? "Replace all"
? BegTime
? EndTime
use
use test
BegTime=time()
locate for alltrim(username)="352781"
EndTime=time()
? "Locate"
? BegTime
? EndTime
use
------------
program Test;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils, gs6_Shel;
var
MyTable: TgsDBFTable;
EndTime, BegTime: Tdatetime;
FieldNo: word;
FromRec, ToRec : Integer;
begin
MyTable := TgsDBFTable.Create("test.DBF","",true,false);
MyTable.First;
BegTime:= Time;
while not MyTable.EOF do
begin
Writeln(MyTable.StringGet("USERNAME"));
MyTable.Next;
end;
EndTime:= Time;
Writeln("Scan and print");
Writeln(TimeToStr(BegTime));
Writeln(TimeToStr(EndTime));
MyTable.First;
BegTime:= Time;
while not MyTable.EOF do
begin
MyTable.Next;
end;
EndTime:= Time;
Writeln("Scan");
Writeln(TimeToStr(BegTime));
Writeln(TimeToStr(EndTime));
MyTable.First;
BegTime:= Time;
while not MyTable.EOF do
begin
MyTable.Edit;
MyTable.StringPut("USERNAME", IntToStr(MyTable.RecNo));
MyTable.Next;
end;
EndTime:= Time;
Writeln("Scan and replace");
Writeln(TimeToStr(BegTime));
Writeln(TimeToStr(EndTime));
MyTable.First;
FieldNo := MyTable.FieldNo("USERNAME");
FromRec := 1;
ToRec := 0;
BegTime:= Time;
MyTable.SearchDBF("352700", FieldNo, FromRec, ToRec);
EndTime:= Time;
MyTable.Free;
Writeln("Search");
Writeln(TimeToStr(BegTime));
Writeln(TimeToStr(EndTime));
readln;
end.
← →
edd (2002-06-26 14:22) [11]2 Viewer
А можно посмотреть на ваш tsvDBF?
← →
Viewer (2002-06-26 15:23) [12]Для 352781 записи
BDE Paradox
Сканирование без чтения - 3 сек
Сканирование с чтением в переменную - 21 сек
Размер файла 25 Мb.
tsvDBF только для создания, чтения, навигации - так что интереса для Вас мало.
Советую перейти на DBISAM.
← →
sniknik (2002-06-26 16:53) [13]Зачем ты затеял эту бодягу? Ничего же не слушаеш. (сужу по сравнению исходников в начале и последних)
как можно сравнивать вывод в текстовом моде (пересылка 5 - 20 байт в видеобуфер) и графику (сложная обработка труетайп шрифтов формирование образа и разнесение как минимум по четырем плоскостям для отображения + псевдомногозадачность - т.е. вызов кучи системных функций в теле твоей программы)
А валить все на доступ к базе? вот как у меня фокс быстро читает и выводит!
и чтение MyTable.StringGet("USERNAME")) по имени! в очередной раз. Потрасируй исходники (у Halcyon-а они есть) посмотри как чтение по имени идет, разбор заголовка (иной раз не маленького) нахождение порядкового номера поля и в конце вызов StringGetN() и так каждый раз в цикле! Операции с текстом подольше выполняются чем просто смещение найти. Тем не менее ты заставляеш дельфи так работать а фокс все оптимизирует под смещение (на то он и расчитан, для баз как никак)
размер твоего файла тоже заставляет задуматся то ли там 255 полей или в пять раз больше удаленных записей чем живых. А что стоит по умолчанию там и там знаеш? имею ввиду как обработка идет Deleted записей?
Ты делай все правильно и тогда Фокс всетаки будет обгонять но не так впечатляюще, а с той скоростью что тот же Halcyon показывает вполне можно работать, и на базах побольше твоей.
Для поиска обычно индексы используют.
для модератора рацпредложение сразу ветки по сравнению "слона" с "ежиком" в потрепатся переносить.
← →
Viewer (2002-06-26 17:10) [14]Все мы учились не сразу.
← →
edd (2002-06-27 07:07) [15]2 Viewer
> tsvDBF только для создания, чтения, навигации - так что интереса для Вас мало
и все же, если не жалко, я бы хотел посмотреть на tsvDBF, мне нужно только чтение, для начала.
2 sniknik
Я только начинаю пробовать Delphi, но если вы внимательно посмотрите на исходники, то увидите:
program Test;
{$APPTYPE CONSOLE}
т.е. и Fox и Delphi работают в текстовом режиме. База сделана на основе реальной, нет удаленных записей.
Я пределал на StringGetN() - разницы никакой. Исходник ниже.
Scan and print
8:55:54
8:57:39
Scan
8:57:39
8:57:52
Scan and replace
8:57:52
8:59:14
Search
8:59:14
8:59:29
program Test;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils, gs6_Shel;
var
MyTable: TgsDBFTable;
EndTime, BegTime: Tdatetime;
FieldNo: word;
FromRec, ToRec : Integer;
begin
MyTable := TgsDBFTable.Create("test.DBF","",true,false);
MyTable.First;
FieldNo := MyTable.FieldNo("USERNAME");
BegTime:= Time;
while not MyTable.EOF do
begin
Writeln(MyTable.StringGetN(FieldNo));
MyTable.Next;
end;
EndTime:= Time;
Writeln("Scan and print");
Writeln(TimeToStr(BegTime));
Writeln(TimeToStr(EndTime));
MyTable.First;
BegTime:= Time;
while not MyTable.EOF do
begin
MyTable.Next;
end;
EndTime:= Time;
Writeln("Scan");
Writeln(TimeToStr(BegTime));
Writeln(TimeToStr(EndTime));
MyTable.First;
BegTime:= Time;
while not MyTable.EOF do
begin
MyTable.Edit;
MyTable.StringPutN(FieldNo, IntToStr(MyTable.RecNo));
MyTable.Next;
end;
EndTime:= Time;
Writeln("Scan and replace");
Writeln(TimeToStr(BegTime));
Writeln(TimeToStr(EndTime));
MyTable.First;
FromRec := 1;
ToRec := 0;
BegTime:= Time;
MyTable.SearchDBF("352700", FieldNo, FromRec, ToRec);
EndTime:= Time;
MyTable.Free;
Writeln("Search");
Writeln(TimeToStr(BegTime));
Writeln(TimeToStr(EndTime));
readln;
end.
← →
Viewer (2002-06-27 09:36) [16]Выслал на мыло.
Но все же совет - уходи от самопала и dbf.
Используй DBISAM для простых локальных и сетевых app.
Если будут интересно - помогу.
← →
sniknik (2002-06-27 10:44) [17]{$APPTYPE CONSOLE}
не гарантия что програма будет в текстовом режиме работать. она у тебя в окошке открывается? и для теста ты exe файл запускаеш или из под дельфийского отладчика?
результаты у тебя получаются очень уж "неправильные" чтото не так (может памяти в машине маловато, так уж исторически сложилось под windows приложения памяти требуется не в пример больше чем под dos). если не в лом пришли свою таблицу посмотреть (надеюсь 85мг в 5 после архивации влезет, dbf хорошо жмется), пока сам не получу те же результаты (скорее близкие) не поверю.
Кстати не пробовал досовский фокс под родным досом тестировать? результаты будут другие уверяю.
← →
edd (2002-06-27 11:42) [18]2 Viewer
Спасибо получил.
А где взять DBISAM? (За $ не предлагать).
2 sniknik
Запускаю exe, открывается в окошке dos.
Базу лень слать, структура ее ниже, сгенери пустую - для тестов пойдет. А исходники смотри выше.
ЗЫ. База - это history.dbf от Wingate (есть такой прокси), идея - генерация отчетов по базе, а не log файлам.
E:\NEW_WORK\Delphi\TEST.DBF
Количество записей: 352781
N Имя поля Тип Длина
---------------------------------
1 ID Numeric 10
2 COMPNAME Character 20
3 USERNAME Character 20
4 WGUSERNAME Character 20
5 IP_NUMBER Character 15
6 APPNAME Character 15
7 TYPE Numeric 2
8 DESC Character 100
9 STARTTIME Numeric 10
10 DURATION Numeric 10
11 BYTESIN Numeric 10
12 BYTESOUT Numeric 10
---------------------------------
Всего: 243
← →
Viewer (2002-06-27 12:21) [19]DBISAM Trial Version - Version 2.12
http://www.elevatesoft.com/scripts/downloadinfo
Всплывает только окошко напоминания.
Никаких функциональных ограничений нет
← →
sniknik (2002-06-27 15:12) [20]Протестировал, операционка win2000, проц селерон 1000, память 256мг, база и коды выше описаны
вот мои результаты
fox delphi helycon
Scan and print Scan and print
14:23:41 14:34:00
14:23:56 14:36:19
15сек 2мин 19сек
Scan Scan
14:23:56 14:36:19
14:23:58 14:36:20
2сек 1сек
Scan and replace Scan and replace
14:23:58 14:36:20
14:24:16 14:36:45
18сек 25сек
Replace all
14:24:16
14:24:34
Locate Search
14:24:34 14:36:45
14:24:36 14:36:48
2сек 3сек
вполне приемлемо по моему не считая конечно того где вывод на экран но повторяюсь в виндах и досе вывод идет по разному. Для примера повторил тест не в полном (текстовом) экране а в окошке и неожидано для меня время Scan and print уменьшилось до минуты ровно (а я думал больше будет). Но все одно это показатель, нельзя так сравнивать, надо или базы тестировать или остальное а не мешать в кучу.
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2002.07.25;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.006 c