【问题标题】:Faster File Operations C++更快的文件操作 C++
【发布时间】:2016-02-21 17:53:36
【问题描述】:

所以我正在用 c++ 和 opengl 为我的一类人制作一个渲染器。我正在制作一个动画程序以获得额外的功劳,它将在我的渲染器在每一帧中读取它们之前更改文本文件中的值。我的问题是这部分代码写得不够快

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 操作。如果我取出 currFile 操作,它将以所需的 fps 运行。 FPS 设置为 0.033,因此它的速度为 30 fps。当 fps = 0.1 时,它也会运行得足够快。任何优化都会很棒。如果需要查看我的代码的任何其他部分,请告诉我,我会上传。整个事情大约有170行。 currOps、files 和 opsFile 是字符串的向量 sclScale、rotScale 和 locScale 是双精度的向量 currAxis 是整数的向量

【问题讨论】:

  • 另外,opsFile 是一个向量,大​​约有 12 行。
  • 有趣。为什么需要实时写入文件?
  • currFile &lt;&lt; endl; 语句不仅会写入换行符,还会将数据刷新到磁盘。您可能只需要前者,而不需要后者。尝试改用currFile &lt;&lt; '\n';
  • 您是否已经对您的应用进行了概要分析?真的是文件写入是瓶颈,还是你在“currOps.size()”的循环中进行的所有 ascii->float->ascii 转换?

标签: c++ file optimization


【解决方案1】:

以下是一些可能会有所帮助的一般更改:

  1. 我会将curOps 转换为枚举而不是字符串(保存字符串比较。)看起来您应该预处理该容器并构建枚举序列(然后循环中的代码变为@ 987654324@)
  2. 不要将vector&lt;string&gt; 用于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&lt;op&gt;,您可以轻松地从文件中输入和输出,例如,读取:

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

写作:

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

如果这还不够,那么mmap(顺便说一句 - 在 Windows 上也可以:Is there a memory mapping api on windows platform, just like mmap() on linux?

【讨论】:

  • switch case 和 enum 的变化使其现在始终保持 87%。 mmap 听起来是个好主意,但你有例子吗?从我阅读的内容来看,它只是 linux。
  • Windows 有内存映射 API。搜索 MSDN 网站。
  • @DragonTorchSlash:它叫CreateFileMapping
  • 感谢所有提供帮助的人。我现在离我更近了,我想在我弄清楚并实施文件映射之后,我会让它运行得足够快。
【解决方案2】:

尝试改用stdio.h 中的函数。 iostreams are terribly inefficient.

在您的情况下,您只需要fseek() ... fputs()。避免每次都重新打开文件实际上应该有很大帮助。

【讨论】:

    猜你喜欢
    • 2021-03-09
    • 2022-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 2012-08-16
    相关资源
    最近更新 更多