Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2002.05.20;
Скачать: [xml.tar.bz2];

Вниз

Оптимизация...   Найти похожие ветки 

 
Pete   (2002-04-09 08:43) [0]

есть такой *.dpr:
program cypher32;

{$APPTYPE CONSOLE}

uses SysUtils,Classes,Windows;

//************************************************
function Encode(filename:string):boolean;
var
strmR,strmW:TFileStream;
mv:array[0..3] of byte;
buf:Byte;

i:Cardinal;
persent,prsnt:Cardinal;
cord:COORD;
console:HWND;

start,stop:TDateTime;
F:textfile;

begin
strmR:=nil;
StrmW:=nil;
try
strmR:=TFileStream.Create(filename,fmOpenRead);
strmW:=TFileStream.Create(filename+"!",fmCreate);
cord.X:=2; cord.Y:=5;
console:=GetStdHandle(STD_OUTPUT_HANDLE);
persent:=strmR.Size div 100;
prsnt:=0;
start:=Time;
for i:=0 to (strmR.Size-1) do
begin
strmR.ReadBuffer(buf,1);
//*************************
mv[0]:=buf and 3;
mv[1]:=buf and 12;
mv[2]:=buf and 48;
mv[3]:=buf and 192;

mv[0]:=mv[0] shl 6;
mv[1]:=mv[1] shl 2;
mv[2]:=mv[2] shr 2;
mv[3]:=mv[3] shr 6;

buf:=mv[0] + mv[1] + mv[2] + mv[3];
//**********************************
strmW.WriteBuffer(buf,1);

if prsnt<>i div persent then begin
SetConsoleCursorPosition(console,cord);
prsnt:=i div persent;
Write(prsnt,"%"); end;
end;//for
stop:=Time;
try
assignfile(f,"Cypher32.log");
rewrite(f);
writeln(f,Format("Обработано %d байт",[strmR.size]));
writeln(f,Format("начало в %s",[TimeToStr(start)]));
writeln(f,Format("окончание в %s",[TimeToStr(stop)]));
writeln(f,Format("за %s секунд",[TimeToStr(stop-start)]));
closefile(f);
except
Writeln(" error write file: "Cypher32.log"");
closefile(f);
end;
strmR.Free;
strmW.Free;
result:=true;
except
result:=false;
strmR.Free;
strmW.Free;
end;

end;
//************************************************

begin
if ParamCount>0 then
if Encode(ParamStr(1))=true
then WriteLn(" Encode Complete")
else
Writeln(" Enter correct filename");

end.



то что выделино жирно в коде надо как-то оптимизировать.
это просто задачка...

один знакомый предложил такой вариант

buf:=(buf shr 6) + (buf shl 6) + ((buf and 48) shr 2) + ((buf and 12) shl 2);

но скорость не изменилась, 1:1...
может кто-нибудь оптимизирует???? :))))))


 
Digitman   (2002-04-09 09:42) [1]

1. оптимизировать здесь нужно, в 1-ю очередь, не "о что выделино жирно", а порционное чтение из файлового устройства в буфер. Что мешает читать из файла не по одному байту за один раз, а сразу, скажем, по 4кб ?

2. Максимальной производительности механизма перекодировки можно добиться, подготовив заранее таблиу размером в 256 байт для перекодировки. Тогда это выглядело бы примерно так :
buf := EncryptTable[buf]


 
Pete   (2002-04-09 09:59) [2]

1. чтение по 4КБ можно сделать, но размер файла может не быть кратным 4кб, придется ставить дополнительные условия проверки.
2. таблица. это занести все варианты для символов от 0 до 255?
но ведь у меня может будет меняться вариант перестановки, это слишком много таблиц будет...


 
Anatoly Podgoretsky   (2002-04-09 10:22) [3]

mv[0] := buf and 3 shl 6;

Так лучше, но проблема все таки в побайтом чтении, основной резерв здесь, сделай буферизованное чтение и скорость может возрости в разы

mv[0]:=buf and 3;
mv[0]:=mv[0] shl 6;


 
Digitman   (2002-04-09 11:22) [4]

>Pete

>>"придется ставить дополнительные условия проверки"

Так временные затраты на такую проверку будут несоизмеримо меньше затрат на обращение к срытому от тебя нагромождению ф-ций файловой подсистемы при каждой итерации, читающей всего-то по одному байту !

>>"слишком много таблиц"

А зачем тебе их все сразу держать-то ? Расчитай нужную динамически при подготовке к итеративной процедуре перекодировки да и пользуйся ей на здоровье, как закончишь перекодировку - "убей" таблицу, если более не нужна. Ты же, наверное, не собираешься в пределах одного файла менять метод кодирования ?


 
wicked   (2002-04-09 11:28) [5]


> проблема все таки в побайтом чтении

а разве rtl сам не кеширует данные?...


 
Pete   (2002-04-09 11:29) [6]

Спасибо за варианты, попытаюсь воспользоваться вашими советами...

>>Ты же, наверное, не собираешься в пределах
>>одного файла менять метод кодирования?

Нет, а мысль интересная... :)


 
Digitman   (2002-04-09 11:50) [7]

>wicked
Кэширует. Но, прежде чем метод Read() вернет этот самый байт из внутреннего кэша, будет выполнено множество вложенных внутрисистемных вызовов (а любой вызов - это скрытые доп.проверки на корректность параметров). А оно это надо - всякий раз ради получения одного единственного очередного байта из системного кэша запускать всю эту сложную цепочку проверок ?


 
Pete   (2002-04-09 15:28) [8]

Сделал буфер 4096 Байт, теперь файл в 460Мб прогоняет за 58 секунд, а с побайтовым буфером 3Мб за 2:09сек.

снова вопрос, а вот код:

mv[0]:=(buf[n] and 3) shl 6;
mv[1]:=(buf[n] and 12) shl 2;
mv[2]:=(buf[n] and 48) shr 2;
mv[3]:=(buf[n] and 192) shr 6;

buf[n]:=mv[0] + mv[1] + mv[2] + mv[3];


более не оптимизировать???


 
Anatoly Podgoretsky   (2002-04-09 15:41) [9]

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


 
Alx2   (2002-04-09 16:00) [10]

>Pete © (09.04.02 15:28)
Сначала нужно выяснить, что наиболее тормозит задачу. Куда копать. А то на этом коде выиграем 1/1000000 секунды, а слон где-то останется. Определи профилировщиком каким-нибудь тормозное место.


 
Anatoly Podgoretsky   (2002-04-09 16:10) [11]

Очень просто, закоментрий расчеты и измерь время


 
Pete   (2002-04-09 16:15) [12]

да скорость устраивает, просто решил спросить мнение мастеров, а то мне кажется что я не оптимально решаю задачи!! :)))
может это комплекс неполноценности??? :))))))))

Alx2: проблема была в размере буфера. а теперь просто попытки оптимизировать...


 
Anatoly Podgoretsky   (2002-04-09 16:23) [13]

Если время без расчетов изменится незначительно, то не стоит их трограь, а сфокусироваться на метох чтения.


 
Alx2   (2002-04-09 16:33) [14]

>Pete © (09.04.02 16:15)
Я бы попробовал при работе спроецировать эти файлы в память. Пусть Windows сама позаботится об оптимальности чтения. :)
А код (по сравнению с
mv[0]:=buf and 3;
mv[1]:=buf and 12;
mv[2]:=buf and 48;
mv[3]:=buf and 192;

mv[0]:=mv[0] shl 6;
mv[1]:=mv[1] shl 2;
mv[2]:=mv[2] shr 2;
mv[3]:=mv[3] shr 6;

buf:=mv[0] + mv[1] + mv[2] + mv[3]; )
я бы этот оставил:
buf:=(buf shr 6) + (buf shl 6) + ((buf and 48) shr 2) + ((buf and 12) shl 2); - Лаконичнее и понятнее
Хотя скорость его выполнения практически не влияет на общую скорость работы (так как скорость доступа к дисковой памяти с лихвой накрывает выигрыши не нем)



 
Shaman_Naydak   (2002-04-09 17:07) [15]

>> Pete
Я решил приколоться и написать функцию декодирования на асме.. гля, что получилось
function Decode(Val: Byte): Byte; assembler;
asm
mov ah, al // Val уже лежит в al
ror al, 2
rol ah, 2
and ax, 33CCh
add al, ah // Рез-т -> в al
sub ah, ah // не обязательно, на всякий случай
end;

Но народ прав на все 100%.. Овчинка не стоит выделки


 
Alx2   (2002-04-10 07:54) [16]

>Pete © (09.04.02 15:28)
снова вопрос, а вот код:

mv[0]:=(buf[n] and 3) shl 6;
mv[1]:=(buf[n] and 12) shl 2;
mv[2]:=(buf[n] and 48) shr 2;
mv[3]:=(buf[n] and 192) shr 6;

buf[n]:=mv[0] + mv[1] + mv[2] + mv[3];

более не оптимизировать???


Еще вариант:
Где-то объявляем:

Const ByteCnvTable : array [0..255] of byte =
(
0, 64, 128, 192, 16, 80, 144, 208,
32, 96, 160, 224, 48, 112, 176, 240,
4, 68, 132, 196, 20, 84, 148, 212,
36, 100, 164, 228, 52, 116, 180, 244,
8, 72, 136, 200, 24, 88, 152, 216,
40, 104, 168, 232, 56, 120, 184, 248,
12, 76, 140, 204, 28, 92, 156, 220,
44, 108, 172, 236, 60, 124, 188, 252,
1, 65, 129, 193, 17, 81, 145, 209,
33, 97, 161, 225, 49, 113, 177, 241,
5, 69, 133, 197, 21, 85, 149, 213,
37, 101, 165, 229, 53, 117, 181, 245,
9, 73, 137, 201, 25, 89, 153, 217,
41, 105, 169, 233, 57, 121, 185, 249,
13, 77, 141, 205, 29, 93, 157, 221,
45, 109, 173, 237, 61, 125, 189, 253,
2, 66, 130, 194, 18, 82, 146, 210,
34, 98, 162, 226, 50, 114, 178, 242,
6, 70, 134, 198, 22, 86, 150, 214,
38, 102, 166, 230, 54, 118, 182, 246,
10, 74, 138, 202, 26, 90, 154, 218,
42, 106, 170, 234, 58, 122, 186, 250,
14, 78, 142, 206, 30, 94, 158, 222,
46, 110, 174, 238, 62, 126, 190, 254,
3, 67, 131, 195, 19, 83, 147, 211,
35, 99, 163, 227, 51, 115, 179, 243,
7, 71, 135, 199, 23, 87, 151, 215,
39, 103, 167, 231, 55, 119, 183, 247,
11, 75, 139, 203, 27, 91, 155, 219,
43, 107, 171, 235, 59, 123, 187, 251,
15, 79, 143, 207, 31, 95, 159, 223,
47, 111, 175, 239, 63, 127, 191, 255
);


В итоге пишем buf[n] := ByteCnvTable[buf[n]];

По-моему еще быстрее трудно сделать. Но, из чисто теоретического интереса можно попробовать MMX :))



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

Форум: "Потрепаться";
Текущий архив: 2002.05.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.008 c
1-64661
Spike_msu
2002-05-01 22:35
2002.05.20
Как зделать????


14-64832
LazorenkoX
2002-04-11 17:44
2002.05.20
KOL


1-64672
turonix
2002-05-05 18:34
2002.05.20
Как в подпрограмму передать динамический двумерный массив?


1-64659
Alexey-neo
2002-05-08 22:34
2002.05.20
Как сделать вращение чего-либо?


3-64532
ProfiUgl
2002-04-23 15:23
2002.05.20
ADOQuery1 ->> ADOQuery2





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