Форум: "Основная";
Текущий архив: 2004.01.20;
Скачать: [xml.tar.bz2];
ВнизПочему так медленно и как исправить? Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.009 c