Проблема здесь не столько в библиотеке, сколько в том, как библиотека
связана. Конечно, iostream - библиотека среднего размера, но я не
думаю, что она может быть настолько огромной, чтобы заставить программу сгенерировать исполняемый файл
900KB
больше, чем аналогичный, использующий C
функции. Виноват
не iostream
, а gcc
. Точнее, виноват static linking
.
Как бы вы объяснили эти результаты (с помощью вашей программы):
g++ test.cpp -o test.exe SIZE: 935KB
gcc test.cpp -o test.exe -lstdc++ SIZE: 64.3KB
Различные размеры исполняемых файлов генерируются с одинаковыми параметрами сборки
.
Ответ заключается в том, как gcc связывает объектные файлы.
Когда вы сравните выходные данные этих двух команд:
g++ -v test.cpp -o test.exe // c++ program using stream functions
gcc -v test.c -o test.exe // c program that using printf
вы обнаружите, что единственные места, где они отличаются (кроме путей к временным объектным файлам
), находятся в Используемые опции:
C++(iostream) | C(stdio)
-------------------------------
-Bstatic | (Not There)
-lstdc++ | (Not There)
-Bdynamic | (Not There)
-lmingw32 | -lmingw32
-lgcc | -lgcc
-lmoldname | -lmoldname
-lmingwex | -lmingwex
-lmsvcrt | -lmsvcrt
-ladvapi32 | -ladvapi32
-lshell32 | -lshell32
-luser32 | -luser32
-lkernel32 | -lkernel32
-lmingw32 | -lmingw32
-lgcc | -lgcc
-lmoldname | -lmoldname
-lmingwex | -lmingwex
-lmsvcrt | -lmsvcrt
У вас есть преступник прямо наверху. -Bstatic
- это опция, которая появляется
точно после объектного файла, который может выглядеть примерно так:
"AppData\\Local\\Temp\\ccMUlPac.o" -Bstatic -lstdc++ -Bdynamic ....
Если вы поэкспериментируете с опциями и удалите «ненужные» библиотеки,
вы можете уменьшить размер исполняемого файла с 934KB
до 4.5KB
max
в моем случае. Я получил это 4.5KB
, используя -Bdynamic
, флаг -O
и самые важные библиотеки, без которых ваше приложение не может жить, то есть
-lmingw32
, -lmsvcrt
, -lkernel32
. Вы получите 25KB исполняемый файл в этой точке
. Разденьте его до 10KB и UPX до около 4.5KB-5.5KB
.
Вот Makefile для игры, для ударов:
## This makefile contains all the options GCC passes to the linker
## when you compile like this: gcc test.cpp -o test.exe
CC=gcc
## NOTE: You can only use OPTIMAL_FLAGS with the -Bdynamic option. You'll get a
## screenfull of errors if you try something like this: make smallest type=static
OPTIMAL_FLAGS=-lmingw32 -lmsvcrt -lkernel32
DEFAULT_FLAGS=$(OPTIMAL_FLAGS) \
-lmingw32 \
-lgcc \
-lmoldname \
-lmingwex \
-lmsvcrt \
-ladvapi32 \
-lshell32 \
-luser32 \
-lkernel32 \
-lmingw32 \
-lgcc \
-lmoldname \
-lmingwex \
-lmsvcrt
LIBRARY_PATH=\
-LC:\MinGW32\lib\gcc\mingw32\4.7.1 \
-LC:\mingw32\lib\gcc \
-LC:\mingw32\lib\mingw32\lib \
-LC:\mingw32\lib\
OBJECT_FILES=\
C:\MinGW32\lib\crt2.o \
C:\MinGW32\lib\gcc\mingw32\4.7.1\crtbegin.o
COLLECT2=C:\MinGW32\libexec\gcc\mingw32\4.7.1\collect2.exe
normal:
$(CC) -c test.cpp
$(COLLECT2) -Bdynamic $(OBJECT_FILES) test.o -B$(type) -lstdc++ -Bdynamic $(DEFAULT_FLAGS) $(LIBRARY_PATH) -o test.exe
optimized:
$(CC) -c -O test.cpp
$(COLLECT2) -Bdynamic $(OBJECT_FILES) test.o -B$(type) -lstdc++ -Bdynamic $(DEFAULT_FLAGS) $(LIBRARY_PATH) -o test.exe
smallest:
$(CC) -c -O test.cpp
$(COLLECT2) -Bdynamic $(OBJECT_FILES) test.o -B$(type) -lstdc++ -Bdynamic $(OPTIMAL_FLAGS) $(LIBRARY_PATH) -o test.exe
ultimate:
$(CC) -c -O test.cpp
$(COLLECT2) -Bdynamic $(OBJECT_FILES) test.o -B$(type) -lstdc++ -Bdynamic $(OPTIMAL_FLAGS) $(LIBRARY_PATH) -o test.exe
strip test.exe
upx test.exe
CLEAN:
del *.exe *.o
Результаты (YMMV):
// Not stripped or compressed in any way
make normal type=static SIZE: 934KB
make normal type=dynamic SIZE: 64.0KB
make optimized type=dynamic SIZE: 30.5KB
make optimized type=static SIZE: 934KB
make smallest type=static (Linker Errors due to left out libraries)
make smallest type=dynamic SIZE: 25.6KB
// Stripped and UPXed
make ultimate type=dynamic (UPXed from 9728 bytes to 5120 bytes - 52.63%)
make ultimate type=static (Linker Errors due to left out libraries)
Возможная причина включения -Bstatic
в параметры сборки по умолчанию
предназначены для лучшей производительности. Я попытался собрать astyle
с -Bdynamic
и получил
снижение скорости в среднем на 1 секунду, хотя приложение было на
меньше, чем оригинал (400 КБ против 93 КБ, когда UPXed) .
В этой записи блога объясняется, как настроить Vim в качестве IDE Python, он охватывает функциональность, подобную Intellisense:
(источник: отправлено .ch )
Это стандарт в Vim 7. Существует ряд других очень полезных плагинов для разработки Python в Vim, таких как Pyflakes , который проверяет код на лету и Python_fn.vim , который предоставляет функции для управления отступами и блоками кода Python.
Что ж, я думаю, что наиболее динамичный способ изучения Python - это использовать iPython .
У вас есть автозаполнение при использовании табуляции, динамическое поведение, потому что это оболочка, и вы можете получить полную документацию по любому типу объекта / метода:
object.method ?
При разработке я согласен, что PyDev - это круто. Но он тяжелый, поэтому во время обучения текстовый редактор + iPython действительно хорош.
Я бы порекомендовал Komodo Edit . Однако я должен указать на одно: вы не получите ничего лучше того, к чему вы привыкли, с Visual Studio C # intellisense. Динамический характер Python может затруднить выполнение таких функций.
ctags + vim тоже работает нормально, хотя он не такой мощный, как intellisense. Используя это с ipython, вы можете получить онлайн-справку, автоматическое завершение имени и т. Д. Но это, очевидно, ориентировано на командную строку.
Eclipse + pydev также может делать это, но у меня нет опыта с этим: http://pydev.sourceforge.net/
Редактор IDLE , поставляемый с Python, имеет функцию intellisense, которая автоматически обнаруживает импортированные модули, функции, классы и атрибуты.
Я настоятельно рекомендую PyDev . В Pydev вы можете поместить модуль, который вы используете, в Forced Buildins , в основном автозавершение кода будет работать лучше, чем в других IDE, таких как KOMODO EDIT.
Также я думаю IPython очень полезно. Поскольку в IPython это «время выполнения», завершение кода в IPython ничего не пропустит.
Динамическая природа языка имеет тенденцию затруднять анализ типов автозаполнения, поэтому качество различных средств завершения, упомянутых выше, сильно варьируется.
Хотя это не совсем то, что вы просили, Оболочка ipython очень хороша для исследовательской работы. Когда я работаю с новым модулем, я стараюсь втягивать его в ipython и тыкать в него. Попробовав большинство решений, упомянутых выше (хотя с Wing прошло много лет), средства завершения ipython неизменно более надежны. Два основных инструмента для исследования - это заполнение табуляции и добавление вопросительного знака к имени модуля / функции, чтобы получить текст справки, например:
In [1]: import sqlalchemy
In [2]: sqlalchemy.s #tab completion
sqlalchemy.schema sqlalchemy.select sqlalchemy.sql sqlalchemy.subquery
In [2]: sqlalchemy.select? #Shows docstring
In [3]: sqlalchemy.select?? #Shows method source
In [4]: edit sqlalchemy.select #opens the source in an editor
Wingware, например, реализует автозаполнение, см. http://wingware.com / doc / edit / auto-completing .
Среда PyDev для Eclipse имеет функциональные возможности, подобные intellisense для Python. Очень полезно держать интерактивную консоль открытой вместе с функцией help (item)
.
У Pyscripter лучший интеллект, который я встречал :)