Форум: "Потрепаться";
Текущий архив: 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.49 MB
Время: 0.006 c