2013-07-04 2 views
2

Я нашел подобное сообщение на эту тему, но он адресует аспект дизайна, а не производительность, поэтому я публикую это, чтобы понять, как нарушение большого файла c влияет на время компиляции и выполнения ,Разделение одного файла на несколько файлов в C - аспекте производительности

У меня есть большие файлы utils (все мы знаем, что они быстро растут). Я пытаюсь понять, если расщепление файла на модульные функциональные файлы (файлы cookie, memcacheutils.c, stringutils.c, search.c, sort.c, arrayutils.c и т. Д.) Добавили бы штраф за компиляцию и время выполнения ,

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

Я мог быть ужасно неправильным или частично правильным. Ищу руководство всех гуру. Мой текущий файл utils составляет около 150k с 80 + функциями.

Благодарим вас за сообщение.

+0

вы должны оценить штрафное время исполнения или штраф за время вашего проекта. Разбиение большого файла на более мелкие добавляет в целом один или несколько уровней указателя, но может облегчить работу разработчика или сопровождающего. – lucasg

+0

Для удобства обслуживания нарезать этого монстра на кусочки! – alk

+0

Проекты Microsoft Windows - это одна из областей, где нужно импортировать 'windows.h' для каждого файла, который может принимать * навсегда * без кэширования заголовков. Разумный вопрос - спросить, может ли быть повреждена производительность компиляции, разбирая код на несколько файлов. –

ответ

2

Это имело значение, когда у вас были 16-разрядные ПК с разными сегментами. Далеко (и, что еще хуже, «huge») указатели несли стоимость исполнения, поскольку вам приходилось начинать обманывать сегментными регистрами.

В настоящее время с 32-разрядной адресацией не должно быть затрат.В конечном счете, если вы беспокоитесь о производительности, вы начинаете рассматривать «jump tables» в сборке, которая требует, чтобы целевой адрес находился на небольшом расстоянии относительно текущей команды.

В C, то вы действительно должны стремиться поместить свой код в разные модули (читайте о теоретических проблемах программного обеспечения «сплоченность» и «связи»). Не должно быть разницы во времени выполнения. Что касается времени компиляции, это «зависит» - особенно если вы включаете файлы повторно. В большом проекте, имеющем многократные файлы, очень много времени, поскольку вы можете перекомпилировать только ту единицу кода, которая изменилась. В небольшом проекте время компиляции настолько мало, чтобы быть относительно незначительным, чтобы беспокоиться об эффективности.

+0

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

+0

@ Хоган согласился. Однако влияние производительности на более крупные модели памяти было реальностью в то время. –

+1

Отдельные единицы компиляции и модель памяти являются полностью ортогональными. –

1

Время компиляции изменится.

(Примечание. - любая система, и проект, который может сделать добавочную сборку будет получить быстрее)

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

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


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

+0

«Время компиляции изменится». Будет ли это быстрее или медленнее? Я бы предпочел бы быстрее, так как многие объектные файлы не нужно компилировать снова, когда ничего не изменяется внутри .cpp-файла. – hetepeperfan

+0

@hetepeperfan. Это зависит от компилятора, компоновщика и процесса make. Я использовал систему, где она будет быстрее, и системы, где она будет медленнее. – Hogan

3

Вы всегда должны сегментировать свои источники в логических единицах.

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

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

+0

Более быстрая компиляция здесь зависит от системы сборки и компилятора. Существует много компиляторов, которые не могут обеспечить эту скорость. – Hogan

4

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

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

+0

Я видел проекты, которые замедляются, когда плюют на несколько файлов ... Разве не так широко говорить, что это позволит быстрее компилировать - я думаю, что это просто другое. – Hogan

+1

Вот почему я сказал быстрее ** частичный ** компиляция. –

+0

Ах, я получил технически. Справедливая. Я думаю, что ваш ответ может быть неправильно понят. – Hogan

1

Это не добавило бы штраф за производительность. И даже если бы это было так, это преждевременная оптимизация. Единственное, что имеет значение, это время разработки.

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

0

Что касается производительности во время выполнения, я бы рассмотрел возможность выполнения некоторых измерений производительности, в зависимости от того, насколько чувствительны вы должны быть с точки зрения потери производительности. Консенсус по ответам на данный момент заключается в том, что производительность во время выполнения не будет снижаться, разбив файл на более мелкие единицы, но это зависит от вашего определения «производительность».

Если вы действительно обеспокоены малейшей потери производительности, если у вас есть whole program optimization включен, и она эффективна, есть небольшая вероятность того, что компилятор будет пропустить некоторые возможности для оптимизации, если ваш файл разбивается (в зависимости конечно, по стилю кода, использованию глобалов, использованию inlining (имейте в виду, что в некоторых случаях не встраивание может дать лучшие результаты), статические классы/методы, если вы используете C++ и т. д.).

Я подозреваю, что в некоторых случаях края, имеющие один исходный файл, могут давать незначительные улучшения производительности (а в других случаях это может ухудшить производительность!). Тестирование до и после нескольких простых сценариев, в том числе изменение уровня оптимизации компилятора, было бы довольно интересным экспериментом.

Я не думаю, что вы найдете какие-либо жесткие правила, такие как «всегда можно разделить большой набор связанных функций на два исходных файла», но вы можете обнаружить, что для конкретных параметров компилятора и исходные файлы, разделение файлов может даже вызвать тонкости, которые влияют на производительность кэша команд (в зависимости от того, насколько точно выполняется ваше тестирование производительности).

Смежные вопросы