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

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.012 c
1-64656
VJar
2002-05-08 15:12
2002.05.20
Можно ли средствами Delphi узнать цвет


1-64686
AlexMey
2002-05-06 11:03
2002.05.20
Вопрос про глобальное определение объектов.


3-64528
Vasilii
2002-04-22 15:44
2002.05.20
проблемы с IBEvents?


1-64587
Фантом
2002-05-07 16:34
2002.05.20
Где почитать про полигоны, регионы?


1-64579
allrussia
2002-05-07 14:20
2002.05.20
howto