решил написать свой .obj парсер, и столкнулся с небольшой проблемой...
...
std::vector<Math::Vector4<float>> vertices;
std::string line;
std::ifstream inputStream(objFileName);
while (std::getline(inputStream, line))
{
if (line.substr(0, 2) == "v ")
{
std::istringstream stream(line.substr(2));
float x, y, z;
stream >> x;
stream >> y;
stream >> z;
vertices.push_back({ x, y, z, 1.0f });
}
... // Texture coordinate, normals e.t.c.
}
Вопрос заключается в следующем, можно ли как-то оптимизировать в данном случае работу с памятью, но так сказать не во вред удобности? При substr постоянно же будет аллоцироваться новая строка, да и при создании стрима. Хотелось бы как-то ограничиться парой выделений памяти и все на этом, а не фрагментировать кучу такими маленькими выделениями(вектор в дальнейшем будет заменен, так как тоже очень затратно будет происходить реаллоцирование памяти, пока просто хотел бы разобраться со строками)...
В современном С++ всю работу с константными/немодифиуируемыми [под]строками имеет смысл переводить на использование std::string_view
. То есть везде, где в вашей программе явно или концептуально выступает const std::string &
он должен быть заменен на const std::string_view &
. Это относится и к вашему применению substr
. Нет никаких причин формировать целый новый std::string
объект только ради выделения немодифицируемой подстроки.
По уму и std::string::substr
должен был бы возвращать std::string_view
, а не std::string
, но так исторически сложилось и сейчас уже не переделать.
В данном случае можно предложить заменить все
line.substr(i, j)
на
std::string_view(line).substr(i, j)
Это избавит вас от ненужных промежуточных std::string
объектов и сопутствующего выделения памяти.
Или уже с самого начала вы могли после получения line
сразу сформировать
std::string_view line_view = line;
и дальше работать исключительно с line_view
.
Это, однако, не избавит вас от выделения памяти при инициализации std::istringstream
и внутри std::istringstream
. Здесь бы бы полезен парсер для std::string_view
, но готового в стандартной библиотеке нет (кроме sscanf
). Сама стандартная библиотека еще толком не перешла на использование std::string_view
.
Ваше
vertices.push_back({ x, y, z, 1.0f });
это тоже потенциально - ненужное копирование. Возможно, что лучше
vertices.emplace_back(x, y, z, 1.0);
но это уже зависит от свойств Math::Vector4<float>
.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Мне необходимо чтобы виджет занимал минимально возможное пространство, но с учетом того, что он не может быть меньше, чем его содержимоеЕго...