Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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
1-81232
SemFLY
2002-07-14 02:22
2002.07.25
Как правильно вызывать поток ?


1-81220
Sachem
2002-07-14 11:03
2002.07.25
Как узнать от какого компанента произошло событие


3-81174
NetWanderer
2002-07-04 11:41
2002.07.25
Проблемы с видимостью транзакций.


1-81370
Goblinus
2002-07-13 19:18
2002.07.25
Convert


1-81302
Katerina
2002-07-09 09:04
2002.07.25
Кто-нибудь сталкивался с такой проблемой





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский