С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 35, средняя оценка - 4.69
FanOfGun
6 / 6 / 1
Регистрация: 13.10.2012
Сообщений: 101
#1

реализация класса в .h файле хорошо или плохо? - C++

17.08.2013, 21:48. Просмотров 5393. Ответов 61
Метки нет (Все метки)

все знакомые мне ide разделяют класс на два файла: .h с описанием и .cpp с кодом, но, например, в boost .hpp файлы почти всегда содержат и реализацию классов, т.е. так тоже можно. так в чем тогда разница и когда какой способ нужно применять? заранее благодарен
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.08.2013, 21:48
Здравствуйте! Я подобрал для вас темы с ответами на вопрос реализация класса в .h файле хорошо или плохо? (C++):

Такой способ создание экземпляра класса хорошо или плохо? - C++
Объясните пожалуйста в чем есть плохо создавать экземпляр класса вот так? class A{ /*.....*/ }objA; нежели так :

Глобальные указатели. Плохо или хорошо? - C++
Уважаемые знатоки, хотел уточнить один вопрос. Дело в том, что я использую глобальные указатели на объекты. Сами объекты создаются по...

Переменные на русском языке - хорошо или плохо? - C++
в mvs 2012 заметил возможность в проектах c++ переменным, функциям, классам давать русско-буквенные имена. как вы относитесь к...

Статические функции-члены - хорошо или плохо? - C++
Всем привет. Приведу пример такой архитектуры. Есть базовый интерфейс. От него наследуются много конкретных. И есть фабрика,...

Реализация класса в отдельном файле - C++
Изучаю C++ (вернее только начал) по учебнику "Харви М. Дейтел, Пол Дж. Дейтел - Как программировать на C++" и застрял на создании классов в...

Реализация шаблонов класса в инлайн файле - C++
Пытался написать шаблонны MyClass.h #pragma once #define MYCLASS template <typename T> class MyClass { public:

61
Jupiter
19.08.2013, 21:50     реализация класса в .h файле хорошо или плохо?
  #46

Не по теме:

castaway, англ "e" произноситься как "и"

0
castaway
Эксперт С++
4916 / 3024 / 370
Регистрация: 10.11.2010
Сообщений: 11,081
Записей в блоге: 10
Завершенные тесты: 1
19.08.2013, 22:55 #47

Не по теме:

Jupiter, на самом деле, нет. В данном слове английская буква 'e' произносится как русская 'э' ( http://ru.forvo.com/word/header/ ).



Добавлено через 11 минут

Не по теме:

Английское слово "head" произносится как "хэд". Английское слово "bread" произносится как "брэд" ..



Добавлено через 51 минуту

Не по теме:

А самое интересное заключается в том, что слово неправильно произносят в шоу "Уральские пельмени": http://www.youtube.com/watch?v=C8Bz9V3JpU0

0
Evg
Эксперт CАвтор FAQ
18381 / 6429 / 441
Регистрация: 30.03.2009
Сообщений: 17,845
Записей в блоге: 28
19.08.2013, 23:13 #48
Цитата Сообщение от Убежденный Посмотреть сообщение
Скажите, как давно Вы последний раз работали с этим режимом ?
В районе 2000 года (наверное даже пораньше). Интеловским компилятором не пользовался. Имею примерное представление о том, как устроен режим в gcc. Нынешнее устройство режима gcc в общей концепции совпадает с тем, с чем я работал 10 лет назад. Исхожу из того, что интеловский компилятор ведёт себя примерно так же. Потому что в конечном итоге вся межмодульная компиляция сводится к тому, что N файлов объединяются в один на уровне промежуточного представления

Цитата Сообщение от Убежденный Посмотреть сообщение
Время сборки увеличивается, но далеко не в такой прогрессии, как Вы указали.
Например, беру свой текущий проект: примерно 500 cpp-файлов, сборка под x86/amd64.
Общее время сборки порядка 3 минут (на Core-i5 2500). При этом треть этого времени составляет
сборка драйверов и компонентов, не относящихся к C++ и IPO. Да, и я имел дело с header-only
библиотеками, при подключении которых время сборки увеличивалось чуть ли не на порядок.
Не давая, по сути, ничего взамен. Ну кроме простоты сборки, разумеется, это вне вопросов
Надеюсь, что правильно понял описанное. Что из себя представляют эти 500 файлов в плане inline. Т.е. насколько глубоко построено дерево вызовов между модулями? Эффект по производительности от межмодульного режима в рамках проекта (без библиотек) по отношению к модульному замерялся? Я почему спрашиваю - коль скоро ты непосредственно с этим работаешь, то тебе не составит большого труда сделать замер. 3 минуты компиляции меня сильно смущают. Либо там файлы короткие, либо инлайн не глубокий (и, соответственно, не сильно эффективный).

Цитата Сообщение от Убежденный Посмотреть сообщение
Доказательства "плохости" есть ? Если нет - значит, ни о чем
Опять-таки на руках нет. Когда с этим работал непосредственно - было их хоть отбавляй. На коммерческих компиляторах от intel'а и sun microsystems. gcc в те времена ещё слабоват по производительности был, а потому его производительность не мерили. Методика была простая: брались стандартные тестовые пакеты spec92 и spec95, мерили на них производительность на ref-данных. Потом брались реальные задачи, которые работают в пакетном режиме и для которых сравнительно просто померить производительность. Это были sun'овские программы типа архиваторов, компиляторов и всякой подобной лабуды, которые свободно не распространялись, а следовательно, для компилятора это были условно неизвестные задачи. Практически по всем задачам производительность существенно отличалась от того, что было замерено на spec'ах. По тем временам в spec'ах разрешалось подавать дофига произвольных опций, а потому все компиляции spec'ов проводились в специально подобранных пиковых режимах, которые годами вылизывались у разработчиков компиляторов. Как только мы переключаемся на реальную задачу и базовые режимы (без всяких тонких настроек, которые нужно очень долго вылизывать), производительность сразу же резко начинала отличаться.

Моё мнение, что межмодульные режимы - это в том числе и продолжение тех тенденций в погоне за публикуемыми цифрами

Цитата Сообщение от Убежденный Посмотреть сообщение
А знаете, в чем прелесть IPO ? В том, что для его использования не нужно прикладывать
никаких усилий. Он просто включен по умолчанию. Думаю, большинство пользователей, особенно
начинающих, вообще не знают, что их компилятор использует IPO. И тем не менее, получают
все выгоды от него
Чтобы не завязнуть в терминологии, я просто называю этот режим межмодульным. Термином IPO обычно называют межпроцедурные оптимизации (inter-procedural optimisations), ты его упомянул в названии режима (ссылка там не открылась), поэтому я подумал, что таким термином они назвали именно режим с межмодульными оптимизациями. Помодульный IPO нас не интересует, только межмодульный

Цитата Сообщение от Убежденный Посмотреть сообщение
Время компиляции увеличивается незначительно
Вот это и пугает больше всего. То бишь непонятно тогда, за счёт чего должен быть прирост по производительности, если компилятор на анализ и оптимизации не тратит время. А межпроцедурные оптимизации они всё-таки дорогие.

Цитата Сообщение от Убежденный Посмотреть сообщение
Ну а неудобство... В чем оно ?
В том, что модификация одного файла *.cpp (т.е. не хидера) вызывает перекомпиляцию всего проекта. Заявленные тобой 3 минуты на проект из 500 файлов, как я уже говорил, меня смущают. Когда руки доберутся, проверю всё-таки на gcc

Цитата Сообщение от Убежденный Посмотреть сообщение
Ну так может пора ему уже на свалку, этому инлайнингу, раз он не играет существенной роли в оптимизации ?
Ну дак если есть счётная задача на Си++, написанная при помощи stl-контейнеров с использованием пользовательских классов (типа список из экземпляров класса MyClass), то взять и скомпилировать с включенным и выключенным инлайном. Разница будет

Цитата Сообщение от Убежденный Посмотреть сообщение
Это совсем не довод
Для тебя, сидящего на одной архитектуре, не довод. Для тех, кто сразу де пишет программы под несколько платформ - довод

Цитата Сообщение от Убежденный Посмотреть сообщение
Да пожалуйста - разные версии хидера и библиотечного файла. Или разные определения одного и того же метода в h и cpp. Это не во всех ситуациях отслеживается компилятором, а потом такую ошибку можно искать очень долго. При единообразном подходе (реализация или только в cpp, или только в h) она менее вероятна
Эта проблема слишком искусственная. Возникает только в том случае если *.cpp не подключает соотвествующий *.h. Другими словами, нужно иметь очень кривые руки. Проблема того же порядка, что использование указателей. Тот, кто умеет ими пользоваться - будет пользоваться и радоваться жизни, кто не умеет - будет огребать геморрой с утра до ночи

Цитата Сообщение от Убежденный Посмотреть сообщение
Я имел в виду, что писать код, заранее прикидывая степень его "заинлайненности" -
это преждевременная оптимизация
А не надо прикидывать. Нужно просто взять за правило, что всё короткое (Set, Get, перегруженные операторы, конструкторы-деструкторы) нужно делать инлайном и выносить в хидера. А понадобитя оно, или нет - это забота компилятора. Понятно, что есть ряд случаев, когда конструкторы или операторы оказываются нетривиальными и большими и незачем их вытаскивать в хидера

Цитата Сообщение от Убежденный Посмотреть сообщение
Все они поддерживают IPO уже не первый год, поэтому не вижу смысла искать здесь причины, чтобы его не использовать
Для меня самая главная причина, почему не нужно использовать межмодульные оптимизации - это слишком долгая пересборка. После озвученных тобой цифр всё-таки попробую поэкспериментировать на gcc. В твой результат мне не верится. Точнее, верится, но только в том случае, когда межмодульный режим не даёт прироста производительности
0
castaway
19.08.2013, 23:22
  #49

Не по теме:

Evg, Убежденный, почему бы вам не подружиться?! Мне кажется, из вас вышла бы хорошая команда (заметьте, я специально не поставил "кавычки").

0
Убежденный
19.08.2013, 23:34
  #50

Не по теме:


Цитата Сообщение от castaway Посмотреть сообщение
Evg, Убежденный, почему бы вам не подружиться?!
Так мы же не ссоримся

0
Evg
Эксперт CАвтор FAQ
18381 / 6429 / 441
Регистрация: 30.03.2009
Сообщений: 17,845
Записей в блоге: 28
19.08.2013, 23:44 #51
У меня даже появилось соображение, почему тот самый межмодульный режим, которым я пользовался давно, был такой медленный. И даже начинаю верить в твои 3 минуты на 500 файлов. Но пока всё равно подозреваю, что межмодульный IPO (в которые входит в том числе и инлайн) будет неглубоким и неагресссивным, но тем не менее небольшой прирост производительности за счёт небольшого увеличения времени компиляции - это однозначно лучше, чем ничего
0
castaway
19.08.2013, 23:44
  #52

Не по теме:

Цитата Сообщение от Убежденный Посмотреть сообщение
Так мы же не ссоримся
Ну кто бы спорил. Вы не ссоритесь, но команда из вас, вышла бы не плохая...

0
Evg
Эксперт CАвтор FAQ
18381 / 6429 / 441
Регистрация: 30.03.2009
Сообщений: 17,845
Записей в блоге: 28
20.08.2013, 10:14 #53
Цитата Сообщение от Убежденный Посмотреть сообщение
Ну так может пора ему уже на свалку, этому инлайнингу, раз он не играет существенной роли в оптимизации?
За тестам далеко ходить не стал, взял примитивный тест на std::vector

C++
#include <vector>
 
/* Навесим сюда атрибут noinline, чтобы в обоих последующих
 * запусках внутренности функции были одними и теми же,
 * и не зависели от того, как у нас компилятор накрутит цикл
 * в точке вызова данной функции */
template <typename T>
void __attribute__((noinline))
test_copy (const T &lhs, T &rhs)
{
  rhs.clear();
  std::insert_iterator<T> ins_it(rhs, rhs.begin());
  std::copy(lhs.begin(), lhs.end(), ins_it);
}
 
int
main (void)
{
  std::vector<int> lhs, rhs;
  lhs.resize (100000);
  for (int i = 0; i < 10000; i++)
    test_copy (lhs, rhs);
}
Код
$ g++ t.cc -O3
$ time ./a.out
real    0m2.617s
user    0m2.549s
sys     0m0.002s

$ g++ t.cc -O3 -fno-inline
$ time ./a.out
real    1m21.080s
user    1m19.243s
sys     0m0.009s
Первый запуск соответствует "правильной" реализации классов, о которой я писал в посте #31. То есть в заголовочных файлах stl помещается именно реализация методов класса. И сделано оно так для того, чтобы эффективно отработать в совокупности всех используемых в программе контейнеров, шаблонов, пользовательских классов.

Второй запуск с опцией -fno-inlline (который запрещает компилятору делать инлайн) соответствует "академической" реализации классов, в которых интерфейс строго отделён от реализации (т.е. в хидер выносятся только описания, а все реализации остаются в файле *.cpp).

Грамотная реализация (в которой учтено, что компилятор работает с инлайном), как мы видим, отработала быстрее более, чем на порядок. Понятно, что пример искусственный, но он демонстрирует ту концепцию, в рамках которой разрабатывался язык Си++ со своим библиотечным окружением
0
Убежденный
Ушел с форума
Эксперт С++
15708 / 7219 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
20.08.2013, 11:36 #54
Цитата Сообщение от Убежденный
Ну так может пора ему уже на свалку, этому инлайнингу, раз он не играет существенной роли в оптимизации?
Цитата Сообщение от Evg Посмотреть сообщение
Грамотная реализация (в которой учтено, что компилятор работает с инлайном), как мы видим, отработала быстрее более, чем на порядок.
Боюсь, Вы меня неправильно поняли. Я не отрицал полезность встраивания самого по себе.
Имелось в виду, что для современных компиляторов одинаково легко встроить как функцию,
определение которой "под рукой", так и функцию, определение которой находится в другой
единице трансляции/компоновки. То есть, возвращаясь к вопросу о "нанокомпиляторах".

Выполнил Ваш тест три раза (VC++2008, x64, Core i5-2500).
Единственное отличие от оригинального кода: test_copy сделана нешаблонной.

1) main и test_copy размещены в одной единице трансляции.
Результат: 3 минуты 57 секунд.

2) main и test_copy размещены в разных единицах трансляции.
Результат: 3 минуты 54 секунды.

3) main и test_copy размещены в разных единицах трансляции + использована опция LTCG.
Результат: 3 минуты 40 секунд.
0
Evg
Эксперт CАвтор FAQ
18381 / 6429 / 441
Регистрация: 30.03.2009
Сообщений: 17,845
Записей в блоге: 28
20.08.2013, 12:04 #55
Цитата Сообщение от Убежденный Посмотреть сообщение
2) main и test_copy размещены в разных единицах трансляции.
Ты смысл теста неправильно понял. В комментарии перед test_copy написал, почему там атрибут noinline. Размещены они в одном модуле, или не в одном - большой роли не играет. Разница между твоими запусками 1-2 и 3 в том, что было проинлайнена функция test_copy. Но тест ведь вовсе НЕ на инлайн test_copy. Тест на то, что проинлайнятся конструкторы, методы и операторы классе vector, тела которых написаны в инклюдах. Другими словами, мы имеем одномодульный тест, к которому понятие межмодульных оптимизаций (LTCG) не имеет смысла. И вся производительность, вытянутая на этом тесте компилятором за счёт инлайна - она проявляется в одномодульном режиме компиляции за счёт "правильного" написания хидера.

Добавлено через 19 минут
Цитата Сообщение от Evg Посмотреть сообщение
У меня даже появилось соображение, почему тот самый межмодульный режим, которым я пользовался давно, был такой медленный. И даже начинаю верить в твои 3 минуты на 500 файлов
Соображение было следующее. То, с чем я работал раньше, сохраняло в качестве промежуточного представления самую раннюю стадию (т.е. представление высокого уровня очень близко к исходному тексту). Отсутствие замедление компиляции на интеловском компиляторе навело на мысль, что они сохраняют одну из последних стадий представления (т.е. сильно оптимизированное представление, близкое к низкому уровню). На таком представлении уже технически более сложно проводить инлайн и последующие за этим оптимизации (а именно ради последующих оптимизаций и делается инлайн, который сам по себе большого смысла не несёт). А потому последующий инлайн будет работать не сильно эффективно (по сравнению с технологией, которую я видел раньше). Отсюда и такой разброс во времени компиляции.

Попробовал режим -flto на gcc. Предположение по косвенным признакам подтверждается. Попробовал на нашем проекте (порядка 1500 исходников, объём исходников порядка 100 мегабайт). Время компиляции замедлилось несущественно (что-то типа 10%). Производительность не изменилась никак. Возможно, были какие-то ускорения в размерах флуктуаций измерений, но реального увеличения производительности не наблюл.
0
Убежденный
Ушел с форума
Эксперт С++
15708 / 7219 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
20.08.2013, 12:56 #56
Цитата Сообщение от Evg Посмотреть сообщение
Ты смысл теста неправильно понял. В комментарии перед test_copy написал, почему там атрибут noinline. Размещены они в одном модуле, или не в одном - большой роли не играет. Разница между твоими запусками 1-2 и 3 в том, что было проинлайнена функция test_copy.
На самом деле она не была проинлайнена ни в одном из случаев.
Компилятор счел, что для этого нет оснований. Тем не менее, определенная оптимизация все
равно была выполнена. Кстати, на 32-битной машине я с помощью LTCG на этом же тесте получил
еще больший прирост - порядка 25%.

Цитата Сообщение от Evg Посмотреть сообщение
Но тест ведь вовсе НЕ на инлайн test_copy. Тест на то, что проинлайнятся конструкторы, методы и операторы классе vector, тела которых написаны в инклюдах. Другими словами, мы имеем одномодульный тест, к которому понятие межмодульных оптимизаций (LTCG) не имеет смысла. И вся производительность, вытянутая на этом тесте компилятором за счёт инлайна - она проявляется в одномодульном режиме компиляции за счёт "правильного" написания хидера.
В этом тесте отсутствует главное - доказательство того, что реализация в заголовках
приводит к генерации более быстрого кода, чем реализация в исходных файлах.
И это хитро, потому что STL, как и надлежит шаблонным классам, реализована в
заголовках, и подтвердить или опровергнуть обратное, используя код STL, не
представляется возможным.

Думаю, единственная возможность расставить все точки над "i" - это найти какую-нибудь
библиотеку, которая может собираться как в варианте header-only, так и как набор h+cpp.
Возможно, в Boost что-то такое найдется. И вот по результатам ее запуска уже делать выводы.
0
Evg
Эксперт CАвтор FAQ
18381 / 6429 / 441
Регистрация: 30.03.2009
Сообщений: 17,845
Записей в блоге: 28
20.08.2013, 13:08 #57
Цитата Сообщение от Убежденный Посмотреть сообщение
Кстати, на 32-битной машине я с помощью LTCG на этом же тесте получил еще больший прирост - порядка 25%
Без конкретного анализа конкретного бинарника тут сказать что-то сложно. На ум приходят две вещи, благодаря которым в конкретно данном тесте есть профит от LTGC:
- в этом режиме более агрессивно работает инлайн (или какие-то дополнительные оптимизации)
- библиотеки stl поставляются с сохранённым промежуточным представлением.
Других вариантов, почему межмодульные оптимизации имеют эффект на исходнике из одного модуля, я не вижу.

Цитата Сообщение от Убежденный Посмотреть сообщение
В этом тесте отсутствует главное - доказательство того, что реализация в заголовках приводит к генерации более быстрого кода
Я же всё написал. В gcc подаём опцию -fno-inline, после чего мы начинаем работать так же, как если бы методы были реализованы в другом файле. То, что они реализованы и скомпилированы в этом файле, принципиально не отличается, как если бы их код подцепился из другого файла (потому что не один ли фиг из какого места подцепится один и тот же код при линковке).

Естественно, эксперимент на на 100% "чистый", т.к. при реализации в библиотеке могли бы быть использованы другие оптимизации, при реализации в библиотеке была бы совсем другая раскладка по взаимному положению функций (и, соответственно, нагрузке на кэш), но вся это разница - доли процента или проценты. На фоне того, как у нас разница в производительности была в разы

Цитата Сообщение от Убежденный Посмотреть сообщение
И это хитро, потому что STL, как и надлежит шаблонным классам, реализована в
заголовках, и подтвердить или опровергнуть обратное, используя код STL, не
представляется возможным
Я уже писал, что любой пользовательский класс почти наверняка будет использован в совокупности с контейнерами или ещё какими шаблонами из STL. И именно в этом месте инлайн даст огромное преимущество. Преимущество будет в том числе и без работы с STL, но чем меньше размер паровоза из всяких шаблонов, тем меньше будет разница между наличием и отсутствием инлайна. Примитивный пример напишу чуть позже
0
Убежденный
Ушел с форума
Эксперт С++
15708 / 7219 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
20.08.2013, 13:37 #58
Цитата Сообщение от Evg Посмотреть сообщение
Без конкретного анализа конкретного бинарника тут сказать что-то сложно.
Я смотрел ассемблерный код. Он просто разный в некоторых местах.
Думаю, объяснить эффект LTCG можно, если думать про него не как про IPO, а именно
как про вторую фазу оптимизации. Которая в обычном режиме не выполняется.

Цитата Сообщение от Evg Посмотреть сообщение
В gcc подаём опцию -fno-inline, после чего мы начинаем работать так же, как если бы методы были реализованы в другом файле.
Не могу с этим согласиться.
Эффект от -fno-inline более глубокий, чем ты описываешь - он отключает инлайнинг по всему коду.
Если у меня есть функции A и B, размещенные в разных единицах трансляции, то даже без IPO я
могу рассчитывать хотя бы на то, что компилятор встроит код STL в тела A и B.
При использовании -fno-inline и этого встраивания не будет.
0
Evg
Эксперт CАвтор FAQ
18381 / 6429 / 441
Регистрация: 30.03.2009
Сообщений: 17,845
Записей в блоге: 28
20.08.2013, 14:06 #59
Цитата Сообщение от Убежденный Посмотреть сообщение
Эффект от -fno-inline более глубокий, чем ты описываешь - он отключает инлайнинг по всему коду
Да, отключает. Но очень много всего в нашем случае некритично, ибо будет составлять проценты, может десятки процентов. В нашем случае речь шла о разнице более, чем на порядок, а потому всеми этими процентами и десятками процентов можно пренебречь. Во всяком случае для меня это очевидно (т.к. есть опыт в этой области). Но это вовсе не означает, что это так же очевидно тебе и другим. Поэтому привожу обещанный ранее пример. В примере у нас имеются элементы Elem и массив Elem'ов. Создаём массив, инициализируем его, затем инкрементируем значения

========== Реализация методов в хидере ==========

C++
// Файл t1.cc
 
#include "t.h"
 
#define SIZE 10000
#define COUNT 100000
 
/* Атрибут втыкаем для того, чтобы отрезаться от цикловых оптимизаций
 * вточке вызова и замерить условно чистое время работы данной функции */
void __attribute__((noinline))
test_func (void)
{
  Array array (SIZE);
 
  for (int i = 0; i < SIZE; i++)
    {
      Elem elem (i);
      array.Set (i, elem);
    }
 
  for (int i = 0; i < SIZE; i++)
    {
      Elem elem = array.Get (i);
      elem.Set (elem.Get() + 1);
      array.Set (i, elem);
    }
}
 
int
main (void)
{
  for (int i = 0; i < COUNT; i++)
    test_func ();
 
  return 0;
}
C++
// Файл t.h
 
class Elem
{
private:
  int x;
public:
  Elem () { x = 0; }
  Elem (int _x) { x = _x; }
  int Get (void) { return x; }
  void Set (int _x) { x = _x; }
};
 
class Array
{
private:
  Elem *elems;
public:
  Array (unsigned size) { elems = new Elem[size]; }
  ~Array () { delete elems; }
  Elem Get (unsigned index) { return elems[index]; }
  void Set (unsigned index, const Elem &elem) { elems[index] = elem; }
};
Код
$ g++ t1.cc -O3
$ time ./a.out
real    0m1.719s
user    0m1.718s
sys     0m0.001s
========== Реализация методов в отдельном файле ==========

Файл t1.cc остаётся без изменений.

Из файла t.h удаляем все реализации

C++
// Файл t.h
 
class Elem
{
private:
  int x;
public:
  Elem ();
  Elem (int _x);
  int Get (void);
  void Set (int _x);
};
 
class Array
{
private:
  Elem *elems;
public:
  Array (unsigned size);
  ~Array ();
  Elem Get (unsigned index);
  void Set (unsigned index, const Elem &elem);
};
Добавляем файл t2.cc с реализацией методов

C++
// Файл t2.cc
 
#include "t.h"
 
Elem::Elem ()
{
  x = 0;
}
 
Elem::Elem (int _x)
{
  x = _x;
}
 
int
Elem::Get (void)
{
  return x;
}
 
void
Elem::Set (int _x)
{
  x = _x;
}
 
Array::Array (unsigned size)
{
  elems = new Elem[size];
}
 
Array::~Array ()
{
  delete elems;
}
 
Elem
Array::Get (unsigned index)
{
  return elems[index];
}
 
void
Array::Set (unsigned index, const Elem &elem)
{
  elems[index] = elem;
}
Код
$ g++ t1.cc t2.cc -O3
$ time ./a.out
real    0m24.781s
user    0m24.529s
sys     0m0.172s
1
Убежденный
Ушел с форума
Эксперт С++
15708 / 7219 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
20.08.2013, 14:55 #60
+1, спасибо за реальный тест.

Запустил его на своей рабочей машине, код не трогал, только поменял декларацию
"__attribute__((noinline))" на "__declspec(noinline)" (в VC++ это одно и то же).
Также, для более рельефных результатов, я увеличил оба значения SIZE и COUNT в пять раз.

Итак, результаты (x86, Visual C++ 2008, Core i5-2500).

1) Реализация методов в хидере.

Время: 1 минута 3 секунды.

2) Реализация методов в отдельном файле.

И здесь нас ждал вполне предсказуемый фейл.
Время: 4 минуты 9 секунд.

3) Реализация методов в отдельном файле + опция LTCG.

Время: 25 секунд.

Кстати, в точности такой же результат получается, если использовать LTCG для
реализации методов в хидере. Подтверждая, что компилятору без разницы, где находится
определение - в заголовке или в файле реализации.
0
20.08.2013, 14:55
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.08.2013, 14:55
Привет! Вот еще темы с ответами:

Реализация шаблонов класса в инлайн файле - C++
Пытался написать шаблонный класс, реализуя как обычно объявление класса в h файле и определение элемент-функций в с++. Компилятор постоянно...

Можно ли Хорошо посмотреть информацию о графическом файле в разных библиотеках? - C++
Есть имя (понятно с правильным путем, но это неважно). Надо узнать Размер этого графического файла. Разумеется можно файл Прочесть и для...

Реализация класса на базе класса Stack с возможностью !индексирования! - C++
Помогите пожалуйста!!! Нужно реализовать на базе класса stack другой класс с возможностью индексирования, а именно: Например 1 - й...

Перегрузка оператора индексации для класса плохо себя ведёт - C++
Собственно, есть такое дело. #include &lt;iostream&gt; #include &lt;stdio.h&gt; #include &lt;vector&gt; #include &lt;string&gt; using namespace std; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.