Что делает EXE расти в размерах?
Мой исполняемый файл был размером 364 КБ. Он не использовал класс Vector2D, поэтому я реализовал его с перегруженными операторами.
Я изменил большую часть своего кода из
point.x = point2.x;
point.y = point2.y;
to
point = point2;
Это привело к удалению почти 1/3 моих строк кода, и все же мой exe по-прежнему составляет 364 КБ. Что именно заставляет его расти в размерах?
Ответы
Ответ 1
Чем EXEs растет в размерах?
Внешние библиотеки, особенно статические библиотеки и отладочная информация, общий размер вашего кода, библиотека времени выполнения. Больше кода, больше библиотек == больше exe.
Чтобы уменьшить размер exe, вам нужно обработать exe с помощью gnu strip, избавиться от всех статических библиотек, избавиться от C/С++, отключить все проверки выполнения и включить оптимизацию размера компилятора. Работа без ЭЛТ - боль, но это возможно. Также существует wcrt (альтернативная среда исполнения C), созданная для создания небольших приложений (кстати, она не обновлялась/поддерживалась в течение последних 5 лет).
Самый маленький exe, который я смог создать с помощью компилятора msvc, составляет около 16 килобайт. Это было приложение Windows, отображающее одно окно и требуемое msvcrt.dll для запуска. Я немного изменил его и превратил в практическую шутку, которая стирает изображение на мониторе.
Для впечатляющих методов уменьшения размера exe вы можете посмотреть . kkrieger. Это 3D шутер от первого лица, всего 96 килобайт. Игра имеет большой и подробный уровень, поддерживает шейдеры, тени в реальном времени и т.д. I.e. сравнивается с Saurbraten (см. скриншоты). Самое маленькое приложение для рабочих окон (3d-демонстрация с музыкой), с которым я когда-либо сталкивался, составляло 4 килобайта, и использовал методы сжатия и (возможно) недокументированные функции (то есть тот факт, что *.com executbale мог распаковать и запустить win32 exe на windows xp).
В большинстве случаев размер *.exe не должен вас беспокоить (я не видел дискеты в течение нескольких лет), если это разумно (ниже 100 мегабайт). Например, "необоснованный" размер файла см. В сборке отладки Qt 4 для mingw.
Это привело к удалению почти 1/3 моих строк кода, и все же мой exe по-прежнему составляет 364 КБ.
Скорее всего, это вызвано внешними библиотеками, используемыми компилятором, проверками времени выполнения и т.д.
Кроме того, это операция назначения. Если вы не используете настраиваемые типы для x (с конструктором копирования), операция "копировать", скорее всего, приведет к небольшому числу операций, то есть удаление 1/3 строк не гарантирует, что ваш код будет равен 1/3 короче.
Если вы хотите увидеть, насколько сильно повлияли ваши модификации, вы можете "спросить" компилятор для вывода списка asm для обеих версий программы, а затем сравнить результаты (вручную или с помощью diff). Или вы можете разобрать/сравнить обе версии исполняемого файла. BUt Я уверен, что использование полосы GNU или удаление дополнительных библиотек будет иметь больший эффект, чем удаление операторов присваивания.
Ответ 2
Компилятор, вероятно, оптимизировал вашу перегрузку оператора, вставив ее в нее. Поэтому он эффективно компилируется с тем же кодом, что и ваш оригинальный пример. Таким образом, вы можете сократить множество строк кода, перегружая оператор присваивания, но когда компилятор встроен, он принимает содержимое вашего оператора присваивания и привязывает его к строке в вызывающей точке.
Вложение - один из способов увеличения размера исполняемого файла. Это не единственный способ, как вы можете видеть в других ответах.
Ответ 3
Какой тип? Если это два поплавка, тогда компилятор будет неявно делать копию по каждому члену, что было сделано ранее.
РЕДАКТИРОВАТЬ: По-видимому, некоторые люди в сегодняшней толпе не понимали этого ответа и компенсировали ниспровержением. Поэтому позвольте мне уточнить:
Строки кода имеют отношение NO к размеру исполняемого файла. Исходный код сообщает компилятору, какую конвейерную линию создать. Одна строка кода может вызывать сотни, а не тысячи инструкций по сборке. Это особенно верно в С++, где одна строка может вызывать неявное построение объекта, уничтожение, копирование и т.д.
В этом конкретном случае, я полагаю, что "точка" - это класс с двумя поплавками, поэтому использование оператора присваивания будет выполнять поэтапную копию, т.е. он берет каждого члена отдельно и копирует его. Это то же самое, что и раньше, за исключением того, что теперь это делается неявно. Полученная сборка (и, следовательно, исполняемый размер) одинакова.
Ответ 4
Исполняемые файлы чаще всего располагаются на "страницах", а не на дискретных байтах.
Ответ 5
Я думаю, что это хороший пример, почему нельзя слишком беспокоиться о том, что код слишком многословный, если у вас есть хороший оптимизирующий компилятор. Вместо этого всегда четко указывайте код, чтобы коллеги-программисты могли прочитать ваш код и оставить оптимизацию компилятору.
Ответ 6
Некоторые ссылки для просмотра
http://www2.research.att.com/~bs/bs_faq.html#Hello-world
GCC С++" Hello World " program → .exe 500kb большой при компиляции в Windows. Как уменьшить размер?
http://www.catch22.net/tuts/minexe
Как и для Windows, в VС++ может быть активировано множество параметров компилятора, таких как RTTI, обработка исключений, проверка буфера и т.д., которые могут добавить больше за кулисами к общему размеру.
Ответ 7
Когда вы компилируете программу c или С++ в исполняемый файл, компилятор преобразует ваш код в машинный код и применяет оптимизацию по своему усмотрению.
Но просто, больше code = больше машинного кода для генерации = большего размера для исполняемого файла.
Ответ 8
Также проверьте, есть ли у вас много статических/глобальных объектов. Это существенно увеличивает ваш размер exe, если они не ноль инициализируются.
Например:
int temp[100] = {0};
int main()
{
}
размер указанной выше программы составляет 9140 байт на моей Linux-машине.
если я инициализирую temp array до 5, тогда размер будет увеличиваться примерно на 400 байт. Размер нижеприведенной программы на моей машине linux равен 9588.
int temp[100] = {5};
int main()
{
}
Это связано с тем, что нулевые инициализированные глобальные объекты переходят в сегмент .bss, который при инициализации программы сразу же инициализируется. Где в качестве ненулевых инициализированных объектов содержимое будет внедрено в сам exe.