Вопрос о внутренностях STL - PullRequest
3 голосов
/ 01 апреля 2011

В настоящее время я пишу некоторые абстракции ввода-вывода для двоичных данных. На данный момент я не уверен, насколько хорошо STL выполняет некоторые из этих задач. Например, у меня есть много вещей, которые я могу закодировать в двоичном формате либо в char *, либо в std :: vector. Сейчас, когда у меня есть объект такого типа, я просто пишу его с помощью ostream :: write () или выполняю std :: copy в массиве в ostream_iterater в потоке. Теперь мне было интересно, что будет делать внутренняя копия.

Из того, что я слышал, STL разрешено оптимизировать все что угодно. Например, в Теории копия двух векторов, хранящих символы с использованием std :: copy, не должна копировать эти символы побайтно, а должна использовать системные примитивы для копирования фрагментов данных, где они доступны. Как это делается внутренне.

Причина, по которой я спрашиваю это, состоит в том, что я сейчас пытаюсь переключить файл в память mmaped вместо std :: ostreams. Это означает, что запись данных char * будет действительно простой, но запись векторов будет побайтовой. Что я должен был бы предусмотреть в своем классе для STL, чтобы оптимизировать копирование (возможно, с использованием memcpy)? Я предполагаю, что мне нужны правильные итераторы, но что им нужно, так что STL будет знать, что он может просто записывать, а не ходить по ним.

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

Ответы [ 3 ]

1 голос
/ 01 апреля 2011

iostream предназначен для в формате (т.е. текст) IO только . Если вы хотите двоичный ввод-вывод, вы должны использовать streambuf классы.

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

Iostreams использует streambuf внутри, что добавляет слой косвенности и обеспечивает автоматическую буферизацию. Если вам нужна разумная пропускная способность двоичного ввода-вывода, вы можете напрямую использовать производные от streambuf классы (например, fstreambuf) и тестировать их (и отключить синхронизацию со stdio ).

Или вы можете напрямую использовать mmap или write. Эти функции довольно просты в использовании, и должно быть легко написать собственные классы вокруг них.

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

1 голос
/ 01 апреля 2011

Не совсем понятно, о чем вы спрашиваете.Вы упоминаете векторы, std::copy, char* и отображенные в память файлы, но между ними нет очевидной связи.Покажите нам некоторый код или опишите, что вы пытаетесь сделать, и с какими типами данных.

Но общая оптимизация в реализациях STL заключается в использовании memcpy или аналогичного механизма копирования необработанной памяти в качествеПока тип объекта, который вы копируете - это POD.Таким образом, предполагая, что эта оптимизация существует в вашей реализации STL, все, что вам нужно сделать, это убедиться, что копируемые объекты относятся к типу POD.

Но, как уже упоминалось ранее, единственный способ получить надежную информацию о производительности - этоПрофиль / мера / сравните это сами.

1 голос
/ 01 апреля 2011

Если вы не уверены, насколько хорошо работает STL, тестирование ничем не заменит. Сколько времени занимает много времени, чтобы std :: copy часть данных, и сколько времени занимает копирование того же объема данных с использованием memcopy и сравнение.

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

...