2015-11-19 2 views
1

Так что я делаю рендерер в C++ и opengl для моего класса. Я делаю анимационную программу для дополнительного кредита, который изменит значения в текстовом файле непосредственно перед тем, как мой рендерер прочитает их в каждом кадре. Моя проблема заключается в том, что этот раздел кода не записывается достаточно быстроБолее быстрые операции с файлами C++

while (clock() < time_end) 
    { 
     timeStep = clock() + fps * CLOCKS_PER_SEC; 
     for(int k=0; k < currOps.size(); k++) 
     { 
      // increase/decrease each set once for the current timestep 
      // a case for each operation 
      int pos = currAxis[k]; 
      if(currOps[k] == "loc") 
      { 
       opsFile[8+pos] = patch::to_string(atof(opsFile[8+pos].c_str()) + locScale[pos-1]*timeAdjust); 
       //edit this value by loc adjust 
      } 
      else if(currOps[k] == "rot") 
      { 
       opsFile[4+pos] = patch::to_string(atof(opsFile[4+pos].c_str()) + rotScale[pos-1]*timeAdjust); 
       //edit this value by rot adjust 
      } 
      else if(currOps[k] == "scl") 
      { 
       opsFile[pos] = patch::to_string(atof(opsFile[pos].c_str()) + sclScale[pos-1]*timeAdjust); 
       //edit this value by scl adjust 
      } 
     } 
     currFile.close(); //save file and restart so we don't append multiple times 
     currFile.open(files[location[0]].c_str(), ofstream::out); // so we can write to the file after closing 
     for(int j=0; j <opsFile.size(); j++) 
     { 
      // update the file 
      currFile << opsFile.at(j); 
      currFile << "\n"; 
     } 

     while(clock() < timeStep) 
     { 
      //wait for the next time steps 
     } 
    } 

В частности, операции с текущим потоком в конце. Если я возьму операцию currFile, она будет работать с желаемыми fps. FPS установлен на .033, так что он делает 30 кадров в секунду. Также он будет работать достаточно быстро, если fps = 0,1. Любая оптимизация будет отличной. Если вам нужно увидеть какую-либо другую часть моего кода, дайте мне знать, и я загружу. Все это около 170 строк. currOps, файлы и opsFile векторы строк sclScale, rotScale и locScale векторы двойников currAxis является векторы Интс

+0

Кроме того, opsFile вектор с около 12 линий. – DragonTorchSlash

+1

Интересно. Почему файл необходимо записывать в режиме реального времени? – LogicStuff

+5

Оператор 'currFile << endl;' не только записывает новую строку, но также удаляет данные на диск.Скорее всего, вам нужен только первый, но не последний. Попробуйте вместо этого использовать 'currFile << '\ n';'. –

ответ

3

Вот некоторые общие изменения, которые могут помочь: (. Сохранить вам сравнение строк)

  1. Я хотел бы преобразовать curOps в перечисление, а не строки Похоже, вы должны предварительно обработать, что контейнер и строить Последовательность перечислений (тогда ваш код в цикле становится switch)
  2. Не используйте vector<string> для curOps, просто прочитайте поплавки из файла и напишите всплывающие подсказки - это избавит вас от всех этих бессмысленных преобразований в и из строка. Если вы хотите принять его дальше, преобразуйте файл в двоичный файл (если это разрешено упражнением) и сохраните простую структуру, которая содержит необходимые вам поплавки и использует файлы с отображением памяти (вам не нужно увеличивать это, это прямо с помощью только mmap!)

Перед тем как спуститься по маршруту mmap - попробуйте поплавок прочитать/записать из файла. Например, допустим, что каждая «строка» в файле соответствует что-то вроде следующего:

struct transform { 
    double x, y, z; 
}; 

struct op { 
    transform scale, rot, loc; 
}; 

Объявить кучу потока в/из операторов для них (например:

std::ostream& operator<<(std::ostream& os, const transform& tx) { 
    return os << tx.x << ' ' << tx.y << ' ' << tx.z; 
} 
std::istream& operator>>(std::istream& is, transform& tx) { 
    return is >> tx.x >> tx.y >> tx.z; 
} 

(набор похож потребуется для op)

Теперь ваш вектор std::vector<op>, который вы можете легко транслировать в и из файла, например, следующим образом:

op i; 
while(file >> i) { curOps.push_back(i); } 

Чтобы написать:

for (auto o : curOps) file << o << '\n'; 

Если это еще не достаточно, то mmap (кстати - это возможно на окнах тоже: Is there a memory mapping api on windows platform, just like mmap() on linux?)

+0

Смену коммутатора и перемена перечислений теперь составляют 87%. mmap звучит как отличная идея, но есть ли у вас пример? Из того, что я читаю только в Linux. – DragonTorchSlash

+0

Windows имеет API сопоставления памяти. Найдите сайт MSDN. –

+0

@DragonTorchSlash: Он называется ['CreateFileMapping'] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537 (v = vs.85) .aspx) – MSalters

0

Попробуйте использовать функции в stdio.h вместо. iostreams are terribly inefficient.

В вашем случае все, что вам нужно, это fseek() ... fputs(). Избежать повторного открытия файла каждый раз должно фактически помочь довольно много.

+0

На самом деле это не улучшилось. – DragonTorchSlash

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