2015-11-08 7 views
0

У меня есть метод load(..), который загружает содержимое файла в std::wstring. Обычно он обрабатывает довольно большие файлы (до нескольких МБ), и я использую его широко, поэтому я ищу возможности оптимизации (не нарушая простоту «загружать содержимое файла в строку» и не создавая дополнительных зависимостей для других библиотек).Будет ли я извлекать пользу из применения перемещения семантической или обратной оптимизации-значения для функции, которая возвращает содержимое файла как строку?

Следует ли использовать семантику перемещения здесь (я не совсем знаком с этим)? Или способ, которым я написал это, близок к наиболее оптимальным по времени из-за оптимизации возвращаемой стоимости, который будет выполнять компилятор?

inline static std::wstring load(std::wstring filePath) { 
    std::wifstream file(filePath.c_str()); 
    if(file){ 
     std::wstring fileString; 
     fileString.reserve((size_t)file.tellg()); 

     file.seekg(0); 
     while(!file.eof()){ 
      fileString += file.get(); 
     } 
     file.close(); 
     return fileString; 
    } 
    file.close(); 
    ERROR_HANDLE(L"File could not be open:\n" + filePath); 
    return L""; 
} 
+0

Положитесь на использование 'load', если вы используете его как этот' станд :: wstring контента = нагрузки (путь), 'вы уже используете двигаться семантический, двигаться конструктор в этом случае. – fghj

+0

Вам нужно написать механизм перемещения самостоятельно, если вы создаете класс. Вам нужно будет заставить двигаться, если у вас есть что-то среднее между вызовом 'load' и назначением' wstring', который заставляет 'wstring' передавать lvalue. В противном случае движение уже происходит. –

+1

Перемещение происходит в любом случае, но вы непреднамеренно отключите rvo. Правила просты: либо возвратите один и тот же объект по всем путям возврата (nrvo), либо верните временный путь во все пути возврата (urvo). Вы можете смешать два, но тогда происходит только urvo. Таким образом, ваш код оптимизирует редкий случай (файл не существует), но наказывает общий случай (файл существует). – jepio

ответ

1

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

inline bool load(std::string const& path, std::wstring& content) { 
    std::wifstream in(path.c_str()); 
    if (in) { 
     content.assign(std::istreambuf_iterator<wchar_t>(in), 
         std::istreambuf_iterator<wchar_t>()); 
     return true; 
    } 
    else { 
     return false; 
    } 
} 

Там не должно быть никакой необходимости reserve() памяти как content должна быстро оседают на емкости, достаточной для файлов в обработке.

При использовании оригинального интерфейса, то есть возврата строки, легко будет переместить в любом случае: при возврате временного объекта или именованной переменной будет использоваться конструктор перемещения. В идеале, этого шага также избежать, заложив реализацию, чтобы быть жизнеспособной для copy-elision. Например, вы всегда можете вернуть один и тот же объект. Копирование-правило обычно происходит даже для компиляторов, не реализующих ссылки на значения rvalue или для классов без конструкторов перемещения. Я бы реализовать свою функцию, как это:

inline std::wstring load(const std::string& path) { 
    std::wifstream in(path.c_str()); 
    std::wstring result; 
    if (in) { 
     // possibly result.reserve() capacity 
     result.assign(std::istreambuf_iterator<wchar_t>(in), 
         std::istreambuf_iterator<wchar_t>()); 
    } 
    return result; 
} 

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

  • Нет связанных вопросов^_^