Улучшение кода, Уменьшение времени работы программ |
Улучшение кода, Уменьшение времени работы программ |
BlackShadow |
31.05.2004 16:04
Сообщение
#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}, так вот если в модуле, то компилер просто игнорирует! Возможно. |
Romtek |
7.06.2004 22:25
Сообщение
#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- материалы и статьи по разработке ПО, моделирование алгоритмов, обработка и анализ информации, нейронные сети, машинное зрение и прочее.
|
Altair |
8.06.2004 13:52
Сообщение
#23
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Begin и end лишние видимо я поставил, а вот объединить два промежутка, это мысль.
romtek, а скорость увеличится? ИМХО так только нагляднее, а сорость не увеличится. -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
BlackShadow |
15.06.2004 12:32
Сообщение
#24
|
Гость |
Вспомнил один момент такой. При работе с дробями, практичнее фразы типа b:=a/10 заменять на b:=a*0.1
Ну, это так, мелочи... |
Altair |
15.06.2004 19:27
Сообщение
#25
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Цитата Почему-то существует повальное мнение, что кроме применения ассемблера никак нельзя достигнуть увеличения скорости. Нет, ассемблер нужно применять только для шлифовки критических участков кода (черт, это не моя фраза, и не помня откуда она ) Чаще сам алгоритм можно переработать используя только стандартные средства. Кстати конструкция if a and b then хуже, чем if a then if b then, т.к. в случае провала первой подцели (а), второя не будет проверятся! --------- APAL, ИМХО пора бы эту тему закрепить. Сообщение отредактировано: Oleg_Z - 15.06.2004 19:29 -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
Romtek |
15.06.2004 22:08
Сообщение
#26
|
Знаток Группа: Пользователи Сообщений: 303 Пол: Мужской Реальное имя: Роман Репутация: 2 |
Цитата(Oleg_Z) черт, это не моя фраза, и не помня откуда она моя вроде Цитата(Oleg_Z) т.к. в случае провала первой подцели (а), второя не будет проверятся! Complete boolean evaluation (compiler option)Сообщение отредактировано: romtek - 15.06.2004 22:08 -------------------- Romiras HomeLab- материалы и статьи по разработке ПО, моделирование алгоритмов, обработка и анализ информации, нейронные сети, машинное зрение и прочее.
|
BlackShadow |
16.06.2004 13:42
Сообщение
#27
|
Гость |
Да уж, Oleg_Z, это действительно отключается директивами. Другое дело - преобразование сложных логических вычислений. Например:
(a And Not B) Or (Not a And B) = a Xor b. Сообщение отредактировано: volvo - 21.01.2005 0:18 |
Altair |
16.06.2004 15:20
Сообщение
#28
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
BlackShadow, в следующий раз оформляй логические выражения в тег кода.
Насчет преобразования сложных логических вычислений - а все ли логические функции выполняются с одинаковай скоростью ??? Или есть смысл упрощать сложные логические конструкции? Например если 10^n раз проверяется Код Not(A and B) То может это заменить на Код (Not a) or (not b) Тогда мы избавляемся от and. Только есть ли в этом смысл? Думаю, что нет, а если есть, то при очень большом количестве повторов. -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
Romtek |
16.06.2004 16:15
Сообщение
#29
|
Знаток Группа: Пользователи Сообщений: 303 Пол: Мужской Реальное имя: Роман Репутация: 2 |
В первом случае имеем 2 операции, а во втором - 3
-------------------- Romiras HomeLab- материалы и статьи по разработке ПО, моделирование алгоритмов, обработка и анализ информации, нейронные сети, машинное зрение и прочее.
|
Altair |
16.06.2004 20:24
Сообщение
#30
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Да, но во первых операция NOT ИМХО должна выполняться быстрее, а во вторых есть обратный ход.
-------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
Altair |
17.06.2004 13:34
Сообщение
#31
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 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 - 17.06.2004 15:45 -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
Altair |
18.06.2004 14:05
Сообщение
#32
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
REAL почти в 2 раза медленнее ВСЕХ других числовых типов
доказательство в присоединенном коде. Сообщение отредактировано: Oleg_Z - 18.06.2004 14:08 Прикрепленные файлы TEST.PAS ( 3.67 килобайт ) Кол-во скачиваний: 334 -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
P@sh@ |
26.06.2004 7:41
Сообщение
#33
|
Бывалый Группа: Пользователи Сообщений: 180 Пол: Мужской Репутация: 2 |
Oleg_Z
Real потому медленнее, что у него размер нестандартный - 48 бит, кто его такой выдумал, интересно ? а все более-менее современные процы оптимизированы на работу с 32/64-бит данными. к тому же этот тип не поддерживается сопроцессором, поэтому его либо надо переконвертать в нормальный, либо эмулировать... насчет директив - все они есть в диалоговом окошке "Опции компилятора" или как его там. если убрать все проверки, тогда конечно меньше будет объем кода, да и быстрее чуть-чуть, а почему первые две не влияют на размер ? видимо мат.функции хоть и в двух версиях написаны (с сопроцессором и софтварно), но компилируются всегда вместе... |
BlackShadow |
2.07.2004 15:23
Сообщение
#34
|
Гость |
Int64 появился только в 32-битных компиляторах. По своей сути он - то же самое, что LongInt для BP: работа в EAX и EDX вместо AX и DX. Скорость сравнима...
А вот Real - это либо эмуляция либо содвижок... |
Atos |
16.10.2004 8:13
Сообщение
#35
|
Прогрессор Группа: Модераторы Сообщений: 602 Пол: Мужской Реальное имя: Михаил Репутация: 9 |
А вот это, мне кажется, интересно:
Простой пример: итерация по большому двумерному массиву может идти с совершенно разной скоростью, смотря как он обходится: горизонтально или вертикально. Как и в случае с поленом, которое легче раскалывать вдоль волокна, а не поперёк, одно направление может вызывать значительно больше отказов памяти, чем другое, а отказы обслуживаются долго. Даже программистам на ассемблере приходится делать вид, что у компьютера большая плоская память, но в системе виртуальной памяти это всего лишь абстракция, в которой при отказе памяти образуется дырка, так что отдельные обращения к памяти могут занимать значительно больше наносекунд, чем обычно. Взято из этой статьи:http://russian.joelonsoftware.com/Articles...actions.html#c4 А эту статью прочитал просто с наслаждением:Back to Basics |
BlackShadow |
18.10.2004 21:24
Сообщение
#36
|
Гость |
Atos, ну это и лосю понятно. При последовательном переборе ячеек примитивная оптимизация позволяет конкретно сэкономить на загрузки в регистры новых адресов.
З. Ы. : лучший способ инициализации "любомерного" массива одинаковыми значениями - это Fillchar (если меня память не подводит, то в Pascal'е эта функция называется так). |
Atos |
19.10.2004 6:17
Сообщение
#37
|
Прогрессор Группа: Модераторы Сообщений: 602 Пол: Мужской Реальное имя: Михаил Репутация: 9 |
Цитата(BlackShadow @ 18.10.04 18:24) в Pascal'е эта функция называется так). В каком именно Паскале? Цитата Atos, ну это и лосю понятно. Ну, я же не лось... Нет, в принципе, интуитивно понятно, что вроде бы на следующий элемент переходить удобнее, чем на n-й, но почему такой большой выигрыш? Тут увеличиваем смещение на единицу, там - на некоторое чиcло... Или для считывания слеующего элемента есть более быстрая команда? Хотя, наверное, я чушь порю... асм только-только начал трогать. Нельзя ли объяснить "на пальцах", как в обоих случаях будет действовать компилтор? |
GoodWind |
19.10.2004 12:17
Сообщение
#38
|
Автооответчик Группа: Модераторы Сообщений: 1 188 Пол: Мужской Реальное имя: Александр Репутация: 16 |
Цитата В каком именно Паскале? Borland Turbo Pascal 7.0 TMT pascal да и во всех других, скорее всего, есть -------------------- Неадекватная чушь может быть адекватным ответом на неадекватный вопрос. Понятно или разжевать?
|
Atos |
19.10.2004 13:51
Сообщение
#39
|
Прогрессор Группа: Модераторы Сообщений: 602 Пол: Мужской Реальное имя: Михаил Репутация: 9 |
Действительно... Просто никогда её не использовал. Во всех примерах, на которых нас обучали, это делалось в цикле. Как-то прошёл мимо неё, хотя был уверен, что все основные функции помню. К тому же в описании не конкретно про массив, а просто про байты некоторой переменной говорилось. Будем знать.
Про оптимизацию я, кажется, понял. Она может достигаться применением цепочечных команд, которые позволяют процессору одновременно и работать и с регистром, и со счётчиком(как раз сегодня у нас лекция была). Так? Но, интересно, компилятор Паскаля знает, когда выгодней их использовать? Или только ассемблерными вставками? |
Altair |
7.11.2004 15:14
Сообщение
#40
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 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. -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
Текстовая версия | 8.06.2024 9:21 |