IPB
ЛогинПароль:

> Внимание! Действует предмодерация

Подраздел FAQ (ЧАВО, ЧАстые ВОпросы) предназначен для размещения готовых рабочих программ, реализаций алгоритмов. Это нечто вроде справочника, он наполнялся в течение 2000х годов. Ваши вопросы, особенно просьбы решить задачу, не пройдут предмодерацию. Те, кто наполнял раздел, уже не заходят на форум, а с теми, кто на форуме сейчас, лучше начинать общение в других разделах. В частности, решение задач — здесь.

3 страниц V < 1 2 3 >  
 Ответить  Открыть новую тему 
> Улучшение кода, Уменьшение времени работы программ
сообщение
Сообщение #21


Гость






Цитата
Не может компилятор быть таким глупым

А, если ты напишешь так:
Код

Var
 a,b:Integer;
Begin
 a:=5;
 If a=1 Then
   b:=3
End.

Думаешь он под b ничего не выделит?
А не веришь - проверь.
Код

Var
 a,b,c,d,e,f:File;
 q:Integer;
 Addra,Addrq:LongInt;
Begin
 Addrq:=(Seg(q) Shl 4) + Ofs(q);
 Addra:=(Seg(a) Shl 4) + Ofs(a);
 WriteLn(SizeOf(a));
 WriteLn(Addrq-Addra)
End.

Сколько пишет?

Цитата
А как подсчитывать количество обращений, скажем к массиву, или к файлу, или к прерыванию?

1). Ты же за FPC взялся? Помнишь я тебе про свойства говорил? Вот так и подсчитать.
2). См п. 1
3). Перехватить и увеличивать счётчик.

Цитата
Кстати, пока не забыл - здесь говорили что-то о {$M}, так вот если в модуле, то компилер просто игнорирует!

Возможно.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #22


Знаток
****

Группа: Пользователи
Сообщений: 303
Пол: Мужской
Реальное имя: Роман

Репутация: -  2  +


Взято из ООП. Объектно-ориентированное программирование
Цитата
{этой функции черт знает сколько лет. Ее я взял из программы
PWLHack, старой прогрммы для взлома PWL, она хороша тем, что максимально
оптимизированна.}
Код
Function BD.UpStr(S:String):String; {перевод строки в верхний регистр}
Var I:Byte;
Begin
For I:=1 To ORD(S[0]) Do
Begin
Case S[I] Of
 'a'..'z':S[I]:=Chr(Ord(S[I])-$20);
 'а'..'п':S[I]:=Chr(Ord(S[I])-$20);
 'р'..'я':S[I]:=Chr(Ord(S[I])-$50)
End
End;
UpStr:=S
End;

Мой вариант:
Код
Function BD.UpStr(S:String):String; {перевод строки в верхний регистр}
Var I:Byte;
Begin
For I:=1 To ORD(S[0]) Do
Case S[I] Of
 'a'..'z',
 'а'..'п': S[I]:=Dec(S[I], $20);
 'р'..'я': S[I]:=Dec(S[I], $50)
End;
UpStr:=S
End;


--------------------
Romiras HomeLab- материалы и статьи по разработке ПО, моделирование алгоритмов, обработка и анализ информации, нейронные сети, машинное зрение и прочее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #23


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Begin и end лишние видимо я поставил, а вот объединить два промежутка, это мысль.
romtek, а скорость увеличится?
ИМХО так только нагляднее, а сорость не увеличится.


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #24


Гость






Вспомнил один момент такой. При работе с дробями, практичнее фразы типа b:=a/10 заменять на b:=a*0.1
Ну, это так, мелочи...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #25


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Цитата
Почему-то существует повальное мнение, что кроме применения ассемблера никак нельзя достигнуть увеличения скорости. 



Нет, ассемблер нужно применять только для шлифовки критических участков кода (черт, это не моя фраза, и не помня откуда она )
Чаще сам алгоритм можно переработать используя только стандартные средства.
Кстати конструкция if a and b then хуже, чем
if a then if b then, т.к. в случае провала первой подцели (а), второя не будет проверятся!

---------
APAL, ИМХО пора бы эту тему закрепить.

Сообщение отредактировано: Oleg_Z -


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #26


Знаток
****

Группа: Пользователи
Сообщений: 303
Пол: Мужской
Реальное имя: Роман

Репутация: -  2  +


Цитата(Oleg_Z)
черт, это не моя фраза, и не помня откуда она
моя вроде smile.gif

Цитата(Oleg_Z)
т.к. в случае провала первой подцели (а), второя не будет проверятся!
Complete boolean evaluation (compiler option)

Сообщение отредактировано: romtek -


--------------------
Romiras HomeLab- материалы и статьи по разработке ПО, моделирование алгоритмов, обработка и анализ информации, нейронные сети, машинное зрение и прочее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #27


Гость






Да уж, Oleg_Z, это действительно отключается директивами. Другое дело - преобразование сложных логических вычислений. Например:
(a And Not B) Or (Not a And B) = a Xor b.

Сообщение отредактировано: volvo -
 К началу страницы 
+ Ответить 
сообщение
Сообщение #28


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


BlackShadow, в следующий раз оформляй логические выражения в тег кода. smile.gif
Насчет преобразования сложных логических вычислений - а все ли логические функции выполняются с одинаковай скоростью ???
Или есть смысл упрощать сложные логические конструкции?
Например если 10^n раз проверяется

Код

Not(A and B)

То может это заменить на
Код

(Not a) or (not b)

Тогда мы избавляемся от and.
Только есть ли в этом смысл?
Думаю, что нет, а если есть, то при очень большом количестве повторов.


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #29


Знаток
****

Группа: Пользователи
Сообщений: 303
Пол: Мужской
Реальное имя: Роман

Репутация: -  2  +


В первом случае имеем 2 операции, а во втором - 3


--------------------
Romiras HomeLab- материалы и статьи по разработке ПО, моделирование алгоритмов, обработка и анализ информации, нейронные сети, машинное зрение и прочее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #30


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Да, но во первых операция NOT ИМХО должна выполняться быстрее, а во вторых есть обратный ход.


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #31


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Вот еще:
Если в программе используется write и writeln, то следует убрать последнюю, а использовать только write и управляющие символы.
Доказательство преимущества этого способа:
1 байт с проги снимется, т.к. writeln и write процедуры вне кода описанны, и компилтруются в расчете на FAR.
А так, вместо 2 байт на дальнюю модель памяти (т.е. на адрес процедуры) уйдет только 1 байт!


====== добавил позже =======

Облом. Я проверил все.
1. Логические операции бесполезно упрощать!
2. Writeln работает быстрее, чем write('ddfd',#13,#10), и к тому же на 100 кб(!!) меньше код получается (использовался один раз).
3. Сильно уменьшает код (на 150-200 кб) следующие директивы (применять только на уже оптимизированных программах)
Цитата
N+ - сопроцессор
E+ - эмуляция сопроцессора
I- - отключение проверок ввода/вывода
R- - отключение проверок на границы массивов
S- - отмена проверки на переполнение стека
Q- - отмена проверок на границы типов ­(overflow, underflow­)
B- - быстрое вычисление логических условий
D- - отключить информацию для отладки ­(пропадает возможность отлаживать программу!!!­)

(взял с сурсов.) Очень полезные директивы.
Только две первые не влияют на размер.

Сообщение отредактировано: Oleg_Z -


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #32


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


REAL почти в 2 раза медленнее ВСЕХ других числовых типов

доказательство в присоединенном коде.

Сообщение отредактировано: Oleg_Z -


Прикрепленные файлы
Прикрепленный файл  TEST.PAS ( 3.67 килобайт ) Кол-во скачиваний: 485


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #33


Бывалый
***

Группа: Пользователи
Сообщений: 180
Пол: Мужской

Репутация: -  2  +


Oleg_Z
Real потому медленнее, что у него размер нестандартный - 48 бит, кто его такой выдумал, интересно ? а все более-менее современные процы оптимизированы на работу с 32/64-бит данными. к тому же этот тип не поддерживается сопроцессором, поэтому его либо надо переконвертать в нормальный, либо эмулировать...

насчет директив - все они есть в диалоговом окошке "Опции компилятора" или как его там. если убрать все проверки, тогда конечно меньше будет объем кода, да и быстрее чуть-чуть, а почему первые две не влияют на размер ? видимо мат.функции хоть и в двух версиях написаны (с сопроцессором и софтварно), но компилируются всегда вместе...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #34


Гость






Int64 появился только в 32-битных компиляторах. По своей сути он - то же самое, что LongInt для BP: работа в EAX и EDX вместо AX и DX. Скорость сравнима...
А вот Real - это либо эмуляция либо содвижок...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #35


Прогрессор
****

Группа: Пользователи
Сообщений: 602
Пол: Мужской
Реальное имя: Михаил

Репутация: -  9  +


А вот это, мне кажется, интересно:
Простой пример: итерация по большому двумерному массиву может идти с совершенно разной скоростью, смотря как он обходится: горизонтально или вертикально. Как и в случае с поленом, которое легче раскалывать вдоль волокна, а не поперёк, одно направление может вызывать значительно больше отказов памяти, чем другое, а отказы обслуживаются долго. Даже программистам на ассемблере приходится делать вид, что у компьютера большая плоская память, но в системе виртуальной памяти это всего лишь абстракция, в которой при отказе памяти образуется дырка, так что отдельные обращения к памяти могут занимать значительно больше наносекунд, чем обычно.

Взято из этой статьи:http://russian.joelonsoftware.com/Articles...actions.html#c4

А эту статью прочитал просто с наслаждением:Back to Basics
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #36


Гость






Atos, ну это и лосю понятно. При последовательном переборе ячеек примитивная оптимизация позволяет конкретно сэкономить на загрузки в регистры новых адресов.

З. Ы. : лучший способ инициализации "любомерного" массива одинаковыми значениями - это Fillchar (если меня память не подводит, то в Pascal'е эта функция называется так).
 К началу страницы 
+ Ответить 
сообщение
Сообщение #37


Прогрессор
****

Группа: Пользователи
Сообщений: 602
Пол: Мужской
Реальное имя: Михаил

Репутация: -  9  +


Цитата(BlackShadow @ 18.10.04 18:24)
в Pascal'е эта функция называется так).

В каком именно Паскале?

Цитата
Atos, ну это и лосю понятно.

Ну, я же не лось...

Нет, в принципе, интуитивно понятно, что вроде бы на следующий элемент переходить удобнее, чем на n-й, но почему такой большой выигрыш? Тут увеличиваем смещение на единицу, там - на некоторое чиcло... Или для считывания слеующего элемента есть более быстрая команда? Хотя, наверное, я чушь порю... асм только-только начал трогать. Нельзя ли объяснить "на пальцах", как в обоих случаях будет действовать компилтор?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #38


Автооответчик
*****

Группа: Пользователи
Сообщений: 1 188
Пол: Мужской
Реальное имя: Александр

Репутация: -  16  +


Цитата
В каком именно Паскале?

Borland Turbo Pascal 7.0
TMT pascal
да и во всех других, скорее всего, есть


--------------------
Неадекватная чушь может быть адекватным ответом на неадекватный вопрос. Понятно или разжевать?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #39


Прогрессор
****

Группа: Пользователи
Сообщений: 602
Пол: Мужской
Реальное имя: Михаил

Репутация: -  9  +


Действительно... Просто никогда её не использовал. Во всех примерах, на которых нас обучали, это делалось в цикле. Как-то прошёл мимо неё, хотя был уверен, что все основные функции помню. К тому же в описании не конкретно про массив, а просто про байты некоторой переменной говорилось. Будем знать.

Про оптимизацию я, кажется, понял. Она может достигаться применением цепочечных команд, которые позволяют процессору одновременно и работать и с регистром, и со счётчиком(как раз сегодня у нас лекция была). Так?
Но, интересно, компилятор Паскаля знает, когда выгодней их использовать?
Или только ассемблерными вставками?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #40


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Странно, тестирую бытсрую и пирамидальную на скорость, первая бысрее... может я ошибся где-то ?
Вот код:
Код

{$M 65000, 0, 0}
Const
N=9000;
type
x=array[1..N] of real;
Var
a:x;
i:integer;
T:longint;
G:LongInT;


procedure swap (i, j : word);
var
t : real;
begin
t    := a[i];
a[i] := a[j];
a[j] := t
end;

procedure sort (n, t : word);
begin
while ((t shl 1+1 <= n) and (a[t shl 1+1] > a[t]) or (t shl 1 <= n) and (a[t shl 1] > a[t])) do
begin
 if (a[t shl 1+1] >= a[t shl 1]) and (t shl 1 +1 <= n) then
 begin
  swap (t shl 1 +1, t);
  t := t shl 1+1
 end else
 begin
  swap (t shl 1, t);
  t := t shl 1
 end
end;
end;
procedure Sort_Quick(var a:x; left,right:integer);
var
l,r:integer;
B:real;
begin
l:=left;
r:=right;
B:=a[l];
repeat
 while (a[r]>=B) and (l<r) do r:=r-1;
 a[l]:=a[r];
 while (a[l]<=B) and (l<r) do l:=L+1;
 a[r]:=a[l]
until r=l;
a[l]:=B;
If left<L-1 then SORT_QUICK(a,left,l-1);
If r+1<right then Sort_Quick(a,r+1,right);
end;

begin
Randomize;
T:=MemL[$0040:$006C];
FOR G:=1 to 100 do
begin
for i := 1 to n do a[i]:=Random(MaxInt);
for i := n downto 1 do sort (n, i);
for i := n downto 1 do
begin
 swap (1, i);
 sort (i-1, 1);
end;
End;
T:=MemL[$0040:$006C]-T;
Writeln(T);
T:=MemL[$0040:$006C];
FOR G:=1 to 100 do
begin
for i := 1 to n do a[i]:=Random(MaxInt);
Sort_Quick(A,1,n);
End;
 T:=MemL[$0040:$006C]-T;
Writeln(T);

end.


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

3 страниц V < 1 2 3 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 19.04.2024 22:55
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name