Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.01.20;
Скачать: CL | DM;

Вниз

Почему так медленно и как исправить?   Найти похожие ветки 

 
PS   (2004-01-07 19:14) [0]

Здравствуйте, Мастера! Сижу второй час, никак не могу дойти как сделать попроще и чтобы быстро работало. Проблема такая: имеем программу, которая работает с перекодировочными файлами. Формат их такой:

символ_1=символ_2.

Тут все просто. Проблема в другом. Я использую вот такой код при кодировке/перекодировке:


type
PConvertRec = ^TConvertRec;
TConvertRec = record
Chars: array[1..2] of string;
end;
...
FChars: TList;
...
function TCod.Find(Table: Integer; s: string): Integer;
var
i:Integer;
begin
Result:=-1;
for i:=0 to FChars.Count - 1 do
begin
if PConvertRec(FChars[i]).Chars[Table] = s then
begin
Result:=i;
Break;
end;
end;
end;
...
Function TСod.ConvertStr(Const S:String; Rev:Boolean): String;
Var
I,N:Integer;
Begin
Result:="";
For I:=1 To Length(S) Do
Begin

If Rev=False Then
N:=Find(1,S[I])
Else
N:=Find(2,S[I]);

If N<>-1 Then
Begin
If Rev=False Then
Result:=Result+PCodRec(FChars[N]).Chars[2]
Else
Result:=Result+PCodRec(FChars[N]).Chars[1]
End
Else
Result:=Result+S[I];
End;
End;


Т.е при создании таблицы заполняется массив, а потом на его основе и происходит перекодировка. Я думаю, что тормоза из-за того, что при поиске индекса также используется цикл. Получается один цикл в другом. Как вы думаете, что нужно сделать, чтобы ускорить работу этих процедур? Заранее благодарен всем.


 
Anatoly Podgoretsky ©   (2004-01-07 20:03) [1]

Как минимум

Function TСod.ConvertStr(Const S:String; Rev:Boolean): String;
Var
I,N:Integer;
Begin
SetLength(Result, Length(S));

и убрать везде Result:=Result+S[I];, заменив на Result[I] := ...;


 
PS   (2004-01-07 20:55) [2]

2 Anatoly Podgoretsky

Сделал. Результат нулевой. Что еще можно предпринять?


 
Anatoly Podgoretsky ©   (2004-01-07 21:01) [3]

Результат не может быть нулевым, ускорение просто обязано быть.
Приводи новый код.


 
PS   (2004-01-07 21:21) [4]

2 Anatoly Podgoretsky

Ничего нового, кроме одной строчки:


Function TСod.ConvertStr(Const S:String; Rev:Boolean): String;
Var
I,N:Integer;
Begin
SetLength(Result,Length(S));
Result:="";
For I:=1 To Length(S) Do
Begin

If Rev=False Then
N:=Find(1,S[I])
Else
N:=Find(2,S[I]);

If N<>-1 Then
Begin
If Rev=False Then
Result:=Result+PConvertRec(FChars[N]).Chars[2]
Else
Result:=Result+PConvertRec(FChars[N]).Chars[1]
End
Else
Result:=Result+S[I];
End;
End;


Пробовал просто написать Result[I]:=Str[I] - "A call to an OS function failed". Вроде и повода не было...


 
Anatoly Podgoretsky ©   (2004-01-07 21:33) [5]

Что то ты натворил много ошибок в данном простом коде.

SetLength(Result,Length(S));
Result:="";

Второе это абсурд.

Result[I] := PConvertRec(FChars[N]).Chars[2]
Else
Result[I] := PConvertRec(FChars[N]).Chars[1]
End
Else begin
Result := S;
Exit;
End;


 
Anatoly Podgoretsky ©   (2004-01-07 21:36) [6]

Хотя не совсем понятно, что ты в этом коде творишь, меня смущает вызов Find в цикле.


 
PS   (2004-01-07 21:51) [7]

2 Anatoly Podgoretsky



Result[I] := PConvertRec(FChars[N]).Chars[2]
Else
Result[I] := PConvertRec(FChars[N]).Chars[1]



Ага. Так оно и заработало:


type
PConvertRec = ^TConvertRec;
TConvertRec = record
Chars: array[1..2] of string;
end;


 
PS   (2004-01-07 21:58) [8]

> Хотя не совсем понятно, что ты в этом коде творишь, меня
> смущает вызов Find в цикле.

А по-другому вроде бы никак. В этой процедуре ищется индекс строки, в которой находится данный символ. Как это сделать без цикла - без понятия.


 
Anatoly Podgoretsky ©   (2004-01-07 22:06) [9]

Перекодировка обычно проще делается

for I := 1 to Length(S) do S[I] := Table[S[I]];


 
PS   (2004-01-07 22:09) [10]

> Перекодировка обычно проще делается

Я понимаю, но мне иногда надо символы заменять на строки...


 
Anatoly Podgoretsky ©   (2004-01-07 22:19) [11]

Это меняет дело, но вместо абстрактного кода, лучше бы подробно описал задачу.


 
PS   (2004-01-07 22:26) [12]

Описываю подробно: вообще-то все немного не так. Таблици представляют собой такую штуку:

код символа в hex=строка закодированная в mimebase64

Все эти перетрубации для того, чтобы, к примеру код символа из которого нужно перекодировать не совпадал со служебными символами, которые используются в программе. А Mime просто потому, что возможно использование символов разметки (#13#10, #9 и т.д). Сначала хотел в unicode, но, подумав, решил не заморачиваться. Все это дело перекодируется в символы и строки соответственно во время создания моего класса-перекодировщика. Короче, не влияет не на что. Все остальное я писал выше.


 
PS   (2004-01-07 22:26) [13]

Описываю подробно: вообще-то все немного не так. Таблицы представляют собой такую штуку:

код символа в hex=строка закодированная в mimebase64

Все эти перетрубации для того, чтобы, к примеру код символа из которого нужно перекодировать не совпадал со служебными символами, которые используются в программе. А Mime просто потому, что возможно использование символов разметки (#13#10, #9 и т.д). Сначала хотел в unicode, но, подумав, решил не заморачиваться. Все это дело перекодируется в символы и строки соответственно во время создания моего класса-перекодировщика. Короче, не влияет не на что. Все остальное я писал выше.


 
Думкин ©   (2004-01-07 23:01) [14]

Можно вначале зарезервировать достаточное место под результат, при этом вести счетчик реальной длины, в конце обрезать как надо.


 
PS   (2004-01-07 23:19) [15]

2 Думкин

А есть ли смысл?


 
Slym ©   (2004-01-08 05:11) [16]

2 Anatoly Podgoretsky

Твой код не для него... у него разные длинны входа выхода...
8бит символ на 6 бит символ... 4/3, а не байт2байт.

2 PS
А тебе парень... Либо смириться с тормозами либо искать бругой алгоритм... как то:
строку Hex перевести в byte или char (один хрен один байт)... и на основе этого байта сделать массив строк перекодировки...
(1/много)

scode:array[byte]of string;

function TCod.Code256to64(c: char):string;
begin
Result:=scode[byte(c)]
end;
function TCod.Code64to256(s: string):char;
var i:byte;
begin
for i:=0 to 255 do
if scode[i]=s then result:=Char(i);
end;


если пойти еще дальше то заменить массив строк на массив of char т.е. перекодировка char2char (1/1 по длинне) но с base64...
есть еще один способ но он судя по всему не для тебя возня с битами... быстро (если на асме)


 
Думкин ©   (2004-01-08 07:25) [17]

> [15] PS (07.01.04 23:19)

Безусловно, именно эта идея и была у АП - сразу резервировать память, а не гонять ее при каждом писке.


 
Anatoly Podgoretsky ©   (2004-01-08 07:50) [18]

Естественно не подойдет, да и не было бы ее, если бы была объяснена задача, только выделение памяти сразу, а не откусывание ее по байтику Result := Result + ...



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

Текущий архив: 2004.01.20;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.026 c
1-63153
GooG-NTS
2004-01-06 04:44
2004.01.20
Быть с верху!


1-63125
PS
2004-01-07 19:14
2004.01.20
Почему так медленно и как исправить?


8-63261
hedgehoge
2003-09-09 15:47
2004.01.20
Распознавание


14-63331
Juster~~
2003-12-30 07:51
2004.01.20
Как спустить на землю?


1-63140
miracle_fox
2004-01-07 15:52
2004.01.20
добавить из файла в richedit