Значительно ли увеличивает использование STL?

В качестве расширений типа:

public static class TypeExtensions
{
    public static IEnumerable<FieldInfo> GetConstants(this Type type)
    {
        var fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);

        return fieldInfos.Where(fi => fi.IsLiteral && !fi.IsInitOnly);
    }

    public static IEnumerable<T> GetConstantsValues<T>(this Type type) where T : class
    {
        var fieldInfos = GetConstants(type);

        return fieldInfos.Select(fi => fi.GetRawConstantValue() as T);
    }
}
13
задан titaniumdecoy 15 December 2008 в 01:08
поделиться

8 ответов

Вещь о STL, потому что это - все шаблоны это только, добавляет к размеру, когда Вы на самом деле используете. Если Вы не используете метод затем, что метод не инстанцируют.

, Но всегда будет стоимость для вещей, которые Вы используете.

, Но реальный вопрос необходимо спросить. Размер собирается быть больше или меньшим, чем yourt собственная реализация? Если Вы не используете STL, что Вы используете? Можно вручить записи собственное, но это имеет ее собственную стоимость. Это не нулевое пространство, это не будет хорошо протестировано, и Вы не будете применять установленные лучшие методы.

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

Другое сообщение указывает, что код шаблона должен быть встроен или иметь повторные определения.
Это абсолютно НЕПРАВИЛЬНО .

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

, Если не встроенный затем копия метода будет сгенерирована в каждой единице компиляции, которая использует метод. Но ТРЕБОВАНИЕ для компоновщика C++ - то, что это должно удалить ВСЕ кроме ОДНОЙ копии этих методов, когда приложение связано в исполняемый файл. Если бы компилятор не удалил дополнительные копии, то он должен был бы генерировать ошибку компоновщика повторного определения.

Это легко показать:
следующее иллюстрирует что:

  • метод _M_insert_aux () не встраивается.
  • Это помещается в обе единицы компиляции.
  • , Что только одна копия метода находится в заключительном исполняемом файле.

a.cpp

#include <vector>

void a(std::vector<int>& l)
{
    l.push_back(1);
    l.at(0) = 2;
}

b.cpp

#include <vector>

void b(std::vector<int>& l)
{
    l.push_back(1);
    l.at(0) = 2;
}

main.cpp

#include <vector>

void a(std::vector<int>&);
void b(std::vector<int>&);

int main()
{
    std::vector<int>    x;
    a(x);
    b(x);
}

, Проверяющий

>g++ -c a.cpp
>g++ -c b.cpp

>nm a.o
<removed other stuff>
000000a0 S __ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi
<removed other stuff>

>nm b.o
<removed other stuff>
000000a0 S __ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi
<removed other stuff>

>c++filt __ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi
std::vector<int, std::allocator<int> >::_M_insert_aux(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const&)

>g++ a.o b.o main.cpp
nm a.out | grep __ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi
00001700 T __ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi
11
ответ дан Martin York 15 December 2008 в 11:08
поделиться

Нет никакого ответа, так как STL является рядом шаблонов. Шаблоны, по самой своей природе, только компилируются в при использовании. Таким образом, можно включать весь STL и если ни один из него не будет на самом деле использоваться, то место, добавленное STL, будет нулем. Если у Вас есть очень небольшое приложение, которому удается использовать много различных шаблонов с различными специализациями, место может быть большим.

20
ответ дан ctacke 15 December 2008 в 11:08
поделиться

Я предполагаю, что Вы имеете в виду время выполнения память место и таким образом STL контейнеры .

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

Некоторые хорошие методы:

  • , Если Ваша библиотека собирается выставить эти контейнеры через API, Вам, вероятно, придется выбрать между помещением Вашего кода STL в заголовках библиотеки или не использовании STL. Проблема состоит в том, что мой компилятор не должен реализовывать STL тот же способ, которым Ваш сделал.
  • Read, на как и когда контейнеры STL выделяют память. Когда можно визуализировать, как двухсторонняя очередь растет и уменьшается по сравнению с вектором, Вы будете лучше готовы решить, чтобы использовать.
  • , Если необходимо микроуправлять каждым байтом, рассмотрите пишущие пользовательские средства выделения. Это редко необходимо за пределами встроенных систем.
2
ответ дан Drew Dormann 15 December 2008 в 11:08
поделиться
  • 1
    Попытаться использовать bool? закончитесь = победа. DialogResult; ПОСЛЕ победы. ShowDialog ()... Я знаю it' s не обещающий, но let' s попытка. Есть ли еще информация, Вы думаете, что я, возможно, должен был бы воссоздать сценарий? Это - некоторое нечетное поведение... – Carlo 23 May 2009 в 04:09

Игнорирование обсуждения STL в настоящий момент, существует одна неочевидная важная практика для создания низкого места пространства статическая библиотека. Разделите свою библиотеку в столько разрозненных единиц компиляции, сколько Вы можете. Например, если Вы посмотрите libpthread.a, то Вы будете видеть, что каждая функция имеет свою собственную единицу компиляции. Многие компоновщики выведут мертвый код на основе целых единиц компиляции, но не больше мелкомодульные, чем это. Если я только буду использовать несколько функций из pthreads библиотеки, то мой компоновщик введет только те определения и ничто иное. Если бы с другой стороны, вся библиотека была скомпилирована в файл отдельного объекта, то мой компоновщик должен был бы ввести всю библиотеку как единственную "единицу".

Это зависит от набора инструментальных средств, который Вы используете, и он только применяется при создании статических библиотек. Но я видел, что он имеет очень измеримое значение для крупных библиотек, созданных субоптимальным образом.

1
ответ дан Tom 15 December 2008 в 11:08
поделиться

В то время как это не обращается к шаблонам STL, документация для GCC имеет короткий раздел по уменьшению чрезмерного увеличения размера кода при использовании шаблонных шаблонов.

ссылка http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Template-Instantiation.html#Template-Instantiation

2
ответ дан 15 December 2008 в 11:08
поделиться

Специализации STL на основе указателей могут совместно использовать ту же реализацию. Это, с тех пор (пусто *) имеет тот же размер как (интервал *) или (нечто *). Итак, в то время как:

vector⟨ int⟩ и vector⟨ foo⟩ различные реализации.

vector⟨ интервал *⟩ и vector⟨ нечто *⟩ может совместно использовать большую часть той же реализации. Много реализаций STL делают это для сохранения объема потребляемой памяти.

, Если весь шаблон определяется в заголовке, таким образом, он полностью определяется, компиляторы как g ++ автоматически создадут копию в каждой единице компиляции с помощью класса. Как другие сказали, компоновщик удалит повторные определения.

Они также автоматически встроят методы в определении класса для более высоких уровней оптимизации. Но этим можно управлять с параметрами компилятора.

1
ответ дан 15 December 2008 в 11:08
поделиться
  • 1
    Я думаю совершенно верно. Единственным путем мы решим, это должно видеть больше контекста. – PeterAllenWebb 13 June 2009 в 02:25

Используя STL увеличит Ваш двоичный размер для двух основных причин:

Встраивание

По умолчанию, компилятор рассматривает код шаблона как встроенный. Поэтому, если Вы будете использовать std::list<int> в нескольких различных единицах компиляции, , и компилятор встраивает тот код , то у них каждый будут свои собственные локальные встроенные определения std::list<int> функции (который, вероятно, не является грандиозным предприятием, так как компилятор только встроит очень маленькие определения по умолчанию).

Примечание, которые (поскольку Martin указывает в другом месте) умножаются - определенные символы разделяются всеми современными компоновщиками C++ на больших платформах, как описано в документация GCC . Таким образом, если компилятор оставит код шаблона исключительным, то компоновщик удалит дубликаты.

Специализация

из-за самой природы шаблонов C++, std::list<int> потенциально произвольно отличается, чем std::list<double>. На самом деле стандартные мандаты, который std::vector<bool> определяется как битовый вектор, так большинство операций, там полностью отличающиеся, чем значение по умолчанию std::vector<T>.

Только специалист по обслуживанию библиотеки может иметь дело с этим. Одно решение состоит в том, чтобы взять базовую функциональность и "un-templatize" это. Превратите его в структуру данных C-стиля с void* везде. Затем шаблонный интерфейс, который видят нисходящие разработчики, является тонкой оберткой. Уменьшение объема дублированного кода, потому что шаблонные специализации вся доля общее основание.

4
ответ дан Tom 15 December 2008 в 11:08
поделиться
  • 1
    Никакое различие. На самом деле я делаю ту же самую вещь с несколькими другими окнами в том же проекте, и они все хорошо работают. – quinnapi 23 May 2009 в 03:59

На встроенном проекте с пределом 64 КБ я однажды сделал, я не мог даже связать стандартные библиотеки для C. Таким образом, это зависит от того, что необходимо сделать

0
ответ дан Robert Gould 15 December 2008 в 11:08
поделиться
  • 1
    Был бы он быть хорошей идеей для меня переместить мой код packet.cpp в packet.h и переименовать его к чему-то как " пакет hpp" как i' ve, часто замечаемый используемый в повышении? – Daniel Sloof 16 March 2009 в 10:59
Другие вопросы по тегам:

Похожие вопросы: