Об оптимизации кода

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Об оптимизации кода

Сообщение Troublemaker » 25.10.2008 11:43:46

Есть у меня такая конструкция:
Код: Выделить всё
const
    cfexColl='.sac';
    cfoCollections='Коллекции (*'+cfexColl+')|*'+cfexColl
К cfoCollections есть 4 (пока) обращения в исходном тексте. И в готовом экзешнике я вижу 4 экземпляра этой строки. cfexColl, соответственно, присутствует в 8 экземплярах.
Существует ли способ оставить в выходном файле только один экземпляр константы, на который бы из откомпилированного кода были просто ссылки?
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Об оптимизации кода

Сообщение SAK » 25.10.2008 12:21:45

Можно объявить cfoColletcions как типизованную константу:
cfoColletcions: string = 'Коллекции (*'+cfexColl+')|*'+cfexColl;
В этом случае она станет переменной с заданным начальным значением.
SAK
постоялец
 
Сообщения: 158
Зарегистрирован: 18.02.2006 00:45:14
Откуда: Тим

Re: Об оптимизации кода

Сообщение Troublemaker » 25.10.2008 12:32:38

SAK писал(а):объявить cfoColletcions как типизованную константу

Попробую...

Добавлено спустя 6 минут 12 секунд:
Спасибо, полегчало. Однако, не понял, в чем дело:

Вот такая конструкция
Код: Выделить всё
    cfexColl='.sac';
    cfoCollections:string='Коллекции (*'+cfexColl+')|*'+cfexColl;
компилируется нормально,

А вот такая:
Код: Выделить всё
    cfexColl:string='.sac';
    cfoCollections:string='Коллекции (*'+cfexColl+')|*'+cfexColl;
ругается на illegal expression во второй строке.
Не смертельно, конечно - лишних экземпляров стало меньше, но почему же использование типизованной константы считается ошибкой, разве в выражениях для const можно использовать только untyped, или как раз и сработало, что "она становится переменной с предзаданным значением"?

Вообще, что ли, отказаться от составных строковых const и использовать вместо них переменные, которые инициализировать в начале программы..?
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Об оптимизации кода

Сообщение Михаил Крамер » 25.10.2008 14:23:19

Вы правы - во втором варианте cfexColl уже считается переменной и не может быть использовано как начальное значение типизированной константы, поскольку оно должно быть определено на этапе компиляции.

Паскаль - не С++.
Михаил Крамер
новенький
 
Сообщения: 73
Зарегистрирован: 08.02.2008 14:26:40

Re: Об оптимизации кода

Сообщение Troublemaker » 25.10.2008 14:46:21

Михаил Крамер писал(а):cfexColl уже считается переменной

Грустно. У меня там используются цепочки до 5-6 комбинаций констант, когда из типовых кусков составляются фразы и т.п.
В пресловутом Кларионе, которым я в свое время здесь многим мозги запарил, в этом плане полегче. А тут вспоминается фраза из учебника по FORTH-у. Дословно уже не помню, но что-то вроде: "хотя constant описывает неизменяемое значение, но с помощью такой конструкции ... значение constant можно менять так же, как и значение variable" :)
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Об оптимизации кода

Сообщение Михаил Крамер » 25.10.2008 16:00:04

Ну типизированные константы ввела Borland, по моему в версии 5.5. Хотя лучше бы разрешили инициализировать переменные в секции var. да, кстати, с помощью типизированных констант ещё объявляются статические локальные переменные - такие, которые сохраняют значение между вызовами подпрограмм. А так ли вам принципиально, чтобы значение константы не дублировалось в коде? Ведь эдак сохраняется память под переменную, да и быстродействие возрастает.

Кстати, в С наоборот - не бывает констант (если не считать макросов), а бывают "константные переменные".
Михаил Крамер
новенький
 
Сообщения: 73
Зарегистрирован: 08.02.2008 14:26:40

Re: Об оптимизации кода

Сообщение Troublemaker » 25.10.2008 16:23:43

Михаил Крамер писал(а):А так ли вам принципиально, чтобы значение константы не дублировалось в коде? Ведь эдак сохраняется память под переменную, да и быстродействие возрастает.

С учетом размеров современных дисков, лишняя пара-тройка десятков кило текста погоды, конечно, не сделает. Но у меня осталась привычка писать компактный код еще со времен ДВК, где мне, чтобы поднять производительность и сэкономить память, пришлось разобрать на части паскалевскую RTL (какие, на фиг, исходники? дизассемблер Климова DESS и отладчик Дамира Муратова BUG в руки, и вперед с песней!) и переписать на чистом ассемблере практически весь ввод-вывод (консоль и печать) кроме работы с дисками. Удалось сэкономить что-то около 2К. При 56К оперативки (часть которой отнимает ОС, а первые 0.5К отданы под вектора прерываний), это существенный выигрыш.

Да и несущественное падение быстродействия при замене символьных констант ссылками на них тоже не страшно. Но коль при выводе всё равно используются ссылки и вызовы процедур, то почему бы не использовать их и здесь? Нашел, например, сегодня совершенно глупую, казалось бы, процедуру QuotedStr, которая обрамляет переданную ей строку апострофами. Но когда прикинул, сколько лишних апострофов убирается из готового кода, понял, что не так уж она и глупа :)

В общем, я - сторонник компактности, даже если немного пострадает быстродействие. Не думаю, что разницу в несколько долей миллисекунды кто-то заметит кроме профайлера :)
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Об оптимизации кода

Сообщение Михаил Крамер » 25.10.2008 16:38:55

Ну тады вынесете все строки в отдельный модуль, можно обычными глобальными переменными, а инициализацию вставьте в соответствующий раздел модуля.
Михаил Крамер
новенький
 
Сообщения: 73
Зарегистрирован: 08.02.2008 14:26:40

Re: Об оптимизации кода

Сообщение Troublemaker » 25.10.2008 17:04:03

Примерно так я и писал выше:
Troublemaker писал(а):Вообще, что ли, отказаться от составных строковых const и использовать вместо них переменные, которые инициализировать в начале программы..?
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Об оптимизации кода

Сообщение Михаил Крамер » 25.10.2008 17:17:39

Ну в принципе, да.

Добавлено спустя 3 минуты 12 секунд:
Кстати, а представляете, сколько инструкций уйдёт на то, чтобы в ран-тайме конкатенацию сотворить? Плюс передача строк по значению - и т.п. - по моему, кода тоже прибавит....

Добавлено спустя 10 минут 45 секунд:
Кстати, может вам вот это использовать: http://freepascal.ru/wiki/index.php?title=%D0%A0%D0%B5%D1%81%D1%83%D1%80%D1%81%D0%BD%D1%8B%D0%B5_%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8
Михаил Крамер
новенький
 
Сообщения: 73
Зарегистрирован: 08.02.2008 14:26:40

Re: Об оптимизации кода

Сообщение Troublemaker » 25.10.2008 18:01:47

Михаил Крамер писал(а):Кстати, а представляете,

Опять же, см. выше: при нынешних скоростях задержки не существенны, слишком уж они малы, даже в сумме.

Приведу оффтопичный пример. Во всё том же Кларионе "классические" строки имеют фиксированную длину, и функция len возвращает значение, которое было задано в секции описания переменных, независимо от фактической длины данных. Поэтому обычной практикой было использование функции clip(), полный аналог FPC-шной trim(). Учитывая, что в "4GL для разработки бизнес-приложений на основе баз данных", коим является язык Кларион, работы со строками ОЧЕНЬ много, задержек заметно не было.

Так что вынужден счесть ваш довод неактуальным.

Насчет resourcestring - сейчас "курю" programmer's manual. Спасибо за наводку. Правда, что-то такое где-то читал, что эти строки не очень дружат с не-windows системами. Но, по крайней мере, узнал что-то новое.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Об оптимизации кода

Сообщение Sergei I. Gorelkin » 25.10.2008 20:46:15

Вообще, в пределах одного модуля одинаковые строковые константы (AnsiString) должны использовать одну и ту же память. Кроме того, я собственноручно отсылал патч к компилятору, делающий то же самое и для WideString. В 2.2.2 он едва ли вошел, но 2.3.1 должен работать.

Поэтому, если имеется пример, на котором воспроизводится неправильное поведение - мне бы было интересно на него посмотреть.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Об оптимизации кода

Сообщение Troublemaker » 26.10.2008 05:16:50

Sergei I. Gorelkin писал(а):строковые константы (AnsiString) должны использовать одну и ту же память

Код: Выделить всё
unit constants_u;
const
    cfexColl='.sac';
    cfoCollections='Коллекции (*'+cfexColl+')|*'+cfexColl

unit main;
uses constants_u
    ...
    ShowMessage('Данные файлы не будут видны со включенным фильтром "'+cfoCollections+'"');
    ...
    SaveDialog.filter:=cfoCollections
    ...
    OpenDialog.filter:=cfoCollections
    ...

То есть, константы определены в одном модуле, используются в другом. И в готовом .exe текст "Коллекции (*.sac)|*.sac" встречается 4 раза. FPC 2.2.2 из релиза 0.9.26
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Об оптимизации кода

Сообщение Sergei I. Gorelkin » 28.10.2008 18:56:49

Проверил (с fpc 2.3.1). В общем-то, аномалий не выявлено. В вышеприведенном примере получается два экземпляра строки cfoCollections. Первый - как часть аргумента ShowMessage (это тоже константа, поэтому она вычисляется при компиляции). Второй - сама по себе, используется в выражениях с SaveDialog.filter и OpenDialog.filter. Оставшиеся два, наверное, тоже найдутся, если поискать повнимательнее. Например, третий модуль, использующий те же константы, будет тоже хранить их отдельно (глобальной оптимизации пока что нет).

Resourcestring - не панацея. Нужно учесть, что на всех платформах, за исключением винды, линкер не умеет оптимизировать таблицы ресурсных строк, поэтому программа будет содержать все ресурсные строки из всех модулей (а это свалка будь здоров).
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 21

Рейтинг@Mail.ru