Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.011 c
3-63001
AndrewK
2003-12-23 09:50
2004.01.20
Как правильно написать хранимую процедуру?


1-63215
SJ-79
2004-01-09 03:22
2004.01.20
Создание hlp файла


1-63105
del
2004-01-08 07:06
2004.01.20
освобождение памяти


1-63209
sils
2004-01-09 20:42
2004.01.20
Очистка TStringGrid


6-63276
Barsky
2003-11-18 12:51
2004.01.20
Как передать файл через 80-й порт?





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