Размер exe файла приложения

Вопросы программирования и использования среды Lazarus.

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

Re: Размер exe файла приложения

Сообщение evkon » 28.02.2010 05:15:21

В Ubuntu Linux я использую Geany + fp-compiler 2.2.4-3 для консольных приложений вместо тяжёлого Lazarus.

Изображение

Попробовал разные ключи, приведенные выше: -CX и -Xg размер исполняемого файла не уменьшили, а добавили в туже папку ещё файлы libp*.a *.dbg соответственно (где * - название файла);

ключ -XX уменьшил размер маленькой программки (30 строк кода) со 150 kb до 44 kb, что уже хорошо, но больше 17 kb, которые получаются с помощью Turbo Pascal 7 в Windows. Разные компиляторы и ОС, но ради интереса привожу сравнение.

upd: оптимизация с дополнительным ключом -O3 дала выйгрыш в 112 байт.
upd2: fpc-2.4.0-0 -XX: 47.1kb , fpc-2.4.0-0 -XX -O3: 45 kb
evkon
незнакомец
 
Сообщения: 1
Зарегистрирован: 28.02.2010 04:34:52

Re: Размер exe файла приложения

Сообщение Alana » 13.09.2010 11:27:09

Сделав так, так рекомендовал dunin (ссылку на картинки делать не стала):
dunin писал(а):Делай раз:
Делай два:
Делай три:

получилось, что размер программы стал в 8 раз меньше. Но! Точно такая же программа, написанная на делфи, весит всего ишь почти 1 мб. А применив strip.exe размер файла увеличился с 3 665 664 на 3 665 920. Применив оптимизацию в настройках компилятора -ОЗ, размер еще чуточку уменьшился - до 3 665 152.
Alana
новенький
 
Сообщения: 24
Зарегистрирован: 08.09.2010 16:29:13

Re: Размер exe файла приложения

Сообщение Kitayets » 13.09.2010 11:54:54

2Alana

Так и должно быть. LCL + fpc runtime довольно толстые в следствии их "кросплатрменности", и линкуются статически.

Чем больше LCL модулей в uses, тем толще exe-шник. У меня на небольших приложениях с десятком "контролов" - получаются exe-шники примерно по 1,7 Мб. На мой взгляд не критичны, на PC такие размеры. Другое дело всякие PDA и смартфоны...

Для дальнейшего уменьшения размера бинарника, нужно переходить на более лёгкий GUI framework, например FPGUI, или вообще писать на чистом WinAPI, но всё равно размер будет, минимум, в районе 1 мегабайта.

Добавлено спустя 9 минут 53 секунды:
можно ещё отказаться от классов и исключений и писать на паскалевском аналоге языка "СИ", тогда размер екзешника будет под 100Кб....

но если Вы хотите пользоваться всеми преимуществами ООП и Визуального проектирования интерфейса и кроссплатформенностью - то нужно смирится с повышенным размером исполняемого файла.
Kitayets
постоялец
 
Сообщения: 171
Зарегистрирован: 05.05.2010 21:15:24

Re: Размер exe файла приложения

Сообщение coyot.rush » 13.09.2010 13:26:11

Вот фрагмент книги o KOL.(в сочетание fpc+Lazarus+KOL дает 45 кб на пустую форму :!: )
Код: Выделить всё
KOL - объектная библиотека для программирования на языке Паскаль для среды MS Windows.
Владимир Кладов, 2006-2007 /e-mail: vk@kolmck.net /
Немного истории. Примерно в 1996 или 97 году я задумался о переходе с доживающей свой век платформы DOS на платформу Windows. В то время уже пошла в жизнь операционная система Windows 95, сметая на своем пути монстра OS/2, и заполняя практически всю нишу персоналок. Надо было пересаживаться, а для программиста такой переход означает, прежде всего, необходимость выбора нового инструмента для работы. Наиболее естественным казалось взять Borland C++ (версию 4 или 5) и просто в дополнение к тому, что уже было известно, изучить API Windows. Но это сейчас я это понимаю. А тогда это было не очевидно. И мои попытки программировать в Windows одна за другой не увенчивались успехом. Я продолжал ваять интерфейсы а-ля DOS, потому что мне было проще использовать кучу наработанных своих заготовок, чем изучать то, как делать цикл диспетчеризации сообщений между окнами. И вообще было непонятно: а зачем нужен такой цикл? Моя ведь программа - что когда хочу, то тогда и вывожу, когда надо - тогда и ожидаю ввода. По крайней мере, так я думал тогда.

В конце концов, когда у меня появилось свободное время, я начал экспериментировать с новыми компиляторами, разработанными специально уже для новой среды (Windows 95 и Windows NT 3.5). И по совету своего хорошего знакомого Алексея Шадрина (админам – привет от программеров!), в том числе я попробовал и Delphi 2, которая как раз только что была выпущена. И тут же был изумлен простотой работы и главное - очевидной логикой работы в среде IDE. (В том числе меня порадовала и высокая скорость компиляции кода, надо отдать должное фирме Borland - такого быстрого компилятора мне еще не приходилось видеть).

Ради таких удобств в работе я согласен был пожертвовать привязанностью к C/C++, и вспомнить, как пишут код на Паскале. (На первых порах меня доставала необходимость писать := вместо просто =, и begin/end вместо фигурных скобок*, но уже скоро я привык и к :=, и оценил очевидные преимущества begin/end для людей с не-100%-ным зрением, для нас это намного более удобная запись, чем фигурные скобки, которые легко перепутать с обычными, а то и вообще не заметить). Добавлю только, что первая рабочая программа была готова уже через пару дней (!), и она прекрасно работала в многооконной среде, делая именно, то, что от нее и требовалось (печать платежных поручений, а вы как думали - самое востребованное ПО в условиях стихийно развивающихся ООО и ЧП).

С этого момента я стал убежденным сторонником Паскаля, купил нужные для начинающего книжки по Delphi, даже научился созданию компонентов и сделал парочку своих (как помню, это были TCloudHint и TBaloonHint - для показа всплывающих подсказок в виде окошек затейливой формы - облачков и того, что герои комиксов используют для произнесения речи).

Но постепенно меня начала очень не устраивать одна довольно существенная деталь, а именно: размер полученных программ. Он оказывался гигантским, и для того, например, чтобы выкладывать свои произведения в интернете (а я предполагал, что буду заниматься шароварением), требовался довольно толстый канал. Кроме того, место на диске тоже было не резиновое (напоминаю: в те времена винчестер на 40 мегабайт был нормой, это сейчас 200 Гигабайт не кажутся чем-то чрезмерным).

Я думал над этой проблемой, и наконец решил сделать альтернативную библиотеку классов, которая позволяла бы делать меньшие по размеру программы. Назвал ее XCL (eXtreme Class Library). Это действительно был "экстрим". Не разобравшись до конца в истинных причинах монстроподобности Delphi-программ, я в том числе решил сгоряча отказаться и от использования API Windows, где только можно. Т.е. окна регистрировались в Windows, но использовались только как подложка - вся отрисовка и прочее взаимодействие выполнялись своим собственным кодом. Удивительно, однако, что программы все равно получались меньше, чем в VCL. Правда, по мере продвижения вперед задачи все усложнялись, и до реализации собственного TListView я так и не успел дойти.

Тысячи часов программирования, потраченных на XCL, хотя я практически не использовал API, научили меня все же основам Application Programming Interface. Окончательно я осознал свою ошибку, когда проекту исполнился уже почти год. И тогда я задумал и начал другой проект - библиотеку Key Objects Library, в которой упор делался именно на использование возможностей окон рисовать себя самим и обрабатывать самостоятельно большую часть сообщений.

0.1. Начало KOL
0.1.1. Анализ причин громоздкого размера приложений. Архитектурные концепции KOL


Мал золотник, да дорог.
(Русская народная поговорка)

Но прежде чем, начать, я более тщательно проанализировал возможные причины увеличения размера кода, и обдумал различные способы предотвращения подобной ситуации в моей библиотеке. Основная причина громоздких размеров программ, в которых используются классы - это то обстоятельство, что одни классы используют другие, те, в свою очередь, третьи, и так далее, и так до такой степени, когда разорвать связи уже невозможно. Вы указываете в uses ссылку на модуль Forms, или на Dialogs, и все - ваши 350-400 Килобайт в программу добавлены. Значит, нужно создавать свою иерархию классов, в которой использовать только TObject как предка для всех своих классов, и ни в коем случае не обращаться ко всему тому добру, которое лежит в VCL готовенькое к употреблению. (Именно так устроена библиотека ACL Александра Боковикова - в качестве предка используется именно класс TObject).

Я решил пойти еще дальше, и "вспомнить" о самых основах объектного Паскаля (Object Pascal). ("Вспомнить" - в кавычках, потому что самому мне писать на Object Pascal не приходилось, как я уже упоминал выше, в Delphi я пришел из C/C++, а до этого по Паскалю сдавал только экзамены в университете, и сильно ругал этот замечательный язык, просто не понимая его преимуществ). Так вот, в Object Pascal есть слово object, которое означает не что иное как "структура" + "набор методов". Это то, из чего позже родились классы. Мои эксперименты показали, что простой объект, созданный с помощью слова object, позволяет сэкономить размер программы (а самое главное, если не используются классы вообще, а только объекты, то экономится с самого начала еще несколько килобайт кода из системных модулей). Разумеется, у object было несколько недостатков.

Во-первых, при разрушении объекта, в отличие от экземпляра класса, приходится вручную прописывать код для уничтожения объектов, строк, динамических массивов, которые являются полями этого объекта. Это не очень удобно, но экономия кода дороже, чем необходимость некоторой ручной работы.

Во-вторых, конструирование таких объектов выглядело весьма непривычно. Чтобы в дальнейшем не путаться записывая что-нибудь вроде new( List, Create ); , я решил все "конструкторы" объектов сделать глобальными функциями вида NewTypename( параметры ): PTypename. (На всякий случай я сделал так же "конструкторы" внутри объекта TControl для создания различных разновидностей визуальных объектов, но, по-видимому, никто ими не пользуется, и я - в том числе).

В-третьих, ... К сожалению, о в-третьих, то есть о совместимости, я узнал много позже: в другом компиляторе с языка Паскаль, Free Pascal, слово object не поддерживалось изначально. Но нашлись люди, которые ради возможности компилировать KOL-программы в этом популярном, и что важно - бесплатном - компиляторе, заставили, уговорили - не знаю точно, как сказать, наконец, проделали сами некоторую работу, и с версии 2.10 Free Pascal стал полностью поддерживать object. Хотя и поздновато, и к этому времени решение уже было найдено: в автоматической конверсии KOL в классы, и KOL-программы прекрасно компилировались в Free Pascal даже без поддержки в нем примитивных объектов.

Еще одна сторона этой несовместимости заключается в наличии некоторых проблемы при просмотре значений свойств объектов в окне просмотра (Watch List) при выполнении пошаговой отладки. Delphi может показывать в качестве значения свойства что попало, вместо истинного значения. Решение данной проблемы заключается в указании внутреннего имени поля вместо свойства, когда это возможно (fCount вместо Count, например).

Есть еще некоторое количество различий в использовании объектов против классов: а именно, поскольку object - это просто структура в памяти, то для организации указателя на некоторый объект, необходимо для каждого объектного типа предусматривать соответствующий тип указателя. (Для классов это не требуется, поскольку тип класса уже эквивалентен типу указателя, т.е. тип представителя класса совпадает с типом самого класса). По той же самой причине, в методах объекта, в отличие от методов класса, переменная Self - это не указатель, а структура полей объекта, и для получения указателя требуется применять операцию взятия адреса @, записывая @ Self везде, где требуется передать или использовать указатель самого объекта, для которого пишется этот метод. (В реализации, эта операция не требует дополнительного кода, так как Self передается в метод по ссылке, то есть в виде указателя, и @ Self - это как раз и есть обращение к регистру, в котором хранится указатель на сам объект в памяти).

Итак, я утвердился в решении не использовать классы (class), а только объекты (object). Дальнейшие мои изыскания и эксперименты показали, что, во-первых, слишком большое число различных объектных типов, и сколько-нибудь слишком разветвленное дерево иерархии наследования недопустимы, если требуется экономия размера кода. А во-вторых, разбиение кода на модули так же вызывает увеличение размера программы. Хотя, во втором случае - и не много, но экономить - значит экономить, и я решил всю библиотеку затолкать в один большой исходный файл, который так и был назван: KOL.pas.*

С проблемой уменьшения дерева иерархии наследования я решил бороться самыми радикальными средствами, а именно: все визуальные объекты представляются одним и тем же объектным типом TControl, прямо произведенным от объектного типа TObj, который я создал в качестве базового типа для своей иерархии. Конструкторы используются различные, наборы методов иногда пересекаются, иногда довольно резко отличаются от одной разновидности визуального объекта к другой, но в любом случае используется один и тот же объектный тип. В результате для всех них используется одна и та же копия таблицы виртуальных методов (vmt), меньше дублирование кода и реже требуются виртуальные методы.

И еще я использовал один очень важный технический прием, который изобрел еще при построении XCL (хоть на что-то моя первая библиотека пригодилась, хотя нет, разумеется, без XCL и KOL бы не было). А именно, при инициализации объектов ни в коем случае нельзя инициализировать все возможные поля (которые, в свою очередь, являются объектами). Эту операцию следует по возможности откладывать "на потом". Например, при создании визуального объекта в KOL инициализация шрифта для окна этого объекта выполняется в самом минимальном возможном объеме. Т.е., шрифт "наследуется" от родительского оконного объекта, при этом, на самом деле, вызывается заглушка - указатель на функцию, которая начинает указывать на действительную функцию, только если в программе модифицировался хотя бы один параметр шрифта. Конечно, вероятность того, что в своем приложении программист изменит шрифт по умолчанию, в обычном случае велика. Но случай, когда программист использует KOL, сам по себе необычный: он говорит о том, что программист не хочет добавлять в программу лишний код. А это и означает, что принятие решения об инициализации полей следует отложить до того момента, когда в приложении такой код востребован. Естественно, если есть такая возможность.

На самом деле, приведенный технический прием невозможен был бы без использования компилятора, обладающего способностью не вставлять в код программы процедуры и функции, на которые нет ссылок в проекте (даже если эти процедуры и функции присутствуют в подключенных модулях, задействованных классах/объектах - лишь бы они не были виртуальными). Именно такой способностью и обладает Delphi (Free Pascal тоже, но в тот момент, когда я начинал KOL, о совместимости с Free Pascal речь не шла, да и не было тогда еще этого компилятора - если я не ошибаюсь). В Delphi эта способность называется smart-linking (т.е. умное связывание).

К сожалению, этот прием, как уже упоминалось, не работает для виртуальных методов. Насколько я понимаю данную проблему (а знатоки Delphi предлагали свое понимание, и оно иногда отличалось), причина банально проста: поскольку ссылка на все виртуальные методы уже присутствует в таблице vmt виртуальных методов класса/объектного типа, то метод учитывается как используемый, даже если в реальности к нему никогда не происходит обращений. Например, если от класса «А» унаследован другой класс «Б», в котором этот метод полностью переопределен, и нет обращения к данному методу предка «А», и - только экземпляры этого унаследованного класса «Б» создаются в модулях проекта. Все равно, раз уже ссылка есть в таблице vmt, то метод будет "зачтен". Поэтому я решил использовать механизм виртуальных методов с большой осторожностью, и в KOL их практически нигде нет.


Читаем внимательно :idea:
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: Размер exe файла приложения

Сообщение Alana » 13.09.2010 13:30:59

У меня в программе компоненты для подключения к базе в отдельном модуле, две формы: на одной две таблицы, 5 кнопок, меню и компонент DataEdit; на второй - одна кнопка. Ну и конечно немного кода. Поэтому-то и терзают сомнения, а не многовато ли весит программа, в которой практически ничего нет. :?:
Alana
новенький
 
Сообщения: 24
Зарегистрирован: 08.09.2010 16:29:13

Re: Размер exe файла приложения

Сообщение Mr.Smart » 13.09.2010 13:51:44

Alana
Это вы так думаете, что кода практически нет, а на самом деле его там ну очень много и много который не используется;)
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Размер exe файла приложения

Сообщение Kitayets » 13.09.2010 14:00:00

2coyot.rush
вот вот, для уменьшения размера, приходится отказываться от одной из фундаментальных концепции ООП - полиморфизма, а также мучатся с синтаксисом. Ну и если всё вместе влезает в 45кбайт, то значит проект не линкуется с sysutils - т.е. не доступны, как минимум исключения, а как масимум - нельзя подключить ни один высокоуровневый объектный (изпользующий классы) модуль т.к. они все зависят от sysutils а это означает писать руками кучу всего, что уже написано и оттестировано.
Kitayets
постоялец
 
Сообщения: 171
Зарегистрирован: 05.05.2010 21:15:24

Re: Размер exe файла приложения

Сообщение coyot.rush » 13.09.2010 14:20:29

Kitayets

Ну и если всё вместе влезает в 45кбайт, то значит проект не линкуется с sysutils - т.е. не доступны, как минимум исключения, а как масимум - нельзя подключить ни один высокоуровневый объектный (изпользующий классы) модуль т.к. они все зависят от sysutils а это означает писать руками кучу всего, что уже написано и оттестировано.

смотрим вот тут http://kolmck.net/r_adds.htm :D
и тут http://kolmck.net/r_system.htm
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: Размер exe файла приложения

Сообщение BamsikPotapov » 21.03.2012 00:38:51

Может так подробно не нужно для тех кто понимает, но я командной строкой никогда не пользуюсь и фразы типа "стрипать" мне никак не помогли при уменьшении размера исполняемого файла.
Расскажу как это сделать если плохо знаешь как обращаться с командной строкой
1. запустить ее просто в XP в пункте выполнить написать cmd.exe в Семёрке просто нажать пуск и выбрать
2. скопировать исполняемый файл в каталог с утилитой strip
3. Прописать путь к файлу утилиты Strip, если у вас уже набрано что-то вроде c:\>Users\Bamsik>(так у меня в семерке)
то нужно написать cd.. и путь "перейдет" в каталог Users, далее еще раз набрать cd..
после чего прописать путь к утилите Strip можно прописать или перетащить ее на командную строку после через пробел написать --strip-all project.exe
в итоге должно быть так C:\lazarus\fpc\2.4.4\bin\i386-win32\strip.exe --strip-all project.exe
4.У кого появится хрень такая "C:\lazarus\fpc\2.4.4\bin\i386-win32\strip.exe --strip-all project.exe: rename: File exists" это значит что утилита Strip имеет недостаточно прав.
5. в свойствах утилиты добавьте всегда запускать от имени администратора
6. после повторить в командной строке C:\lazarus\fpc\2.4.4\bin\i386-win32\strip.exe --strip-all project.exe
и всё у меня стало пучком
НО ПРОЩЕ ПЕРЕТАЩИТЬ ИСПОЛНЯЕМЫЙ ФАЙЛ НА ЭТУ УТИЛИТУ
зачем я лез к командной строке если знал что так просто можно, хрен его знает никогда ей не пользовался вот и решил разобраться.
Аватара пользователя
BamsikPotapov
новенький
 
Сообщения: 54
Зарегистрирован: 31.12.2011 19:30:39
Откуда: Меня в капусте нашли

Re: Размер exe файла приложения

Сообщение alexs » 21.03.2012 21:23:31

BamsikPotapov
Что - то сложное...
1. Надо правильно настроить пути к утилитам в системе. Откройте для себя переменную окружения PATH
2. Пользоваться голым CMD - лишние себе проблемы. Это не bash. Поэтому откроте для себя файл-менеджеры: Far или тот-же тотал (но тотал не по джедайски)...
В остатке у вас будет - зайти менеджером в каталог с проектом (хотя если вы реально работаете - в ФМ у вас этот каталог будеть выбран.
написать strip ИмяВашегоEXE - и всё.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Размер exe файла приложения

Сообщение BamsikPotapov » 21.03.2012 23:21:54

Да нет я просто никогда не пльзовался командной строкой и тут понадобилось, я такой ответ написал потому что считаю что он должен быть таким(по отношению к командной строке) для тех кто не пользовался. Я для прожженых перцев как раз подойдет "стрипать". Мне просто ненравится когда откроешь какую-нибудь тему и там опытный программист гнилым сленгом объясняет незнающему человеку какие-либо вещи. Да я и нашел как в самом Лазарусе при компиляции удалять отладочную информацию.
Просто решил поделиться.
Аватара пользователя
BamsikPotapov
новенький
 
Сообщения: 54
Зарегистрирован: 31.12.2011 19:30:39
Откуда: Меня в капусте нашли

Re: Размер exe файла приложения

Сообщение alexs » 22.03.2012 22:43:01

Я не в качестве бравады написал ответ.
Просто в винде пользоваться голой командной строкой новичку - тяжков.
Насчёт ФМ я не зря написал - поставь и не мучайся. Будут все плюшки, доступные в окошках и ещё куча всего того, что не снилось стандартным виндовым средствам.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Пред.

Вернуться в Lazarus

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

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

Рейтинг@Mail.ru