我目前正在将我的爱好项目从std::fstream
迁移到SDL_RWops
(因为SDL_RWops
是我在Android上加载资源的唯一简单选择。)
从文件中读取效果很好,但写入文件的速度非常慢。
考虑使用以下测试用例:
C标准IO - 0.217193秒
std::FILE *io = std::fopen("o.txt", "w");
for (int i = 0; i < 1024*1024*4; i++)
std::putc('0', io);
std::fclose(io);
C ++流 - 0.278278秒
std::ofstream io("o.txt");
for (int i = 0; i < 1024*1024*4; i++)
io << '0';
io.close();
SDL_RWops: - 17.9893秒
SDL_RWops *io = SDL_RWFromFile("o.txt", "w");
for (int i = 0; i < 1024*1024*4; i++)
io->write(io, "0", 1, 1);
io->close(io);
所有测试用g ++ 5.3.0(mingw-w64)x86和-O3编译。我使用过SDL 2.0.4。
我也试过-O0,结果相似(慢0.02到0.25秒)。
在查看这些结果后,我有一个明显的问题:
为什么SDL_RWops写作性能如此差?
我该怎么做才能让它表现更好?
修改:以下是windows_file_write()
的代码(来自SDL),这是io->write
应指向的内容。 应该做缓冲输出,但我不确定它是如何工作的。
static size_t SDLCALL
windows_file_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
{
size_t total_bytes;
DWORD byte_written;
size_t nwritten;
total_bytes = size * num;
if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE || total_bytes <= 0 || !size)
return 0;
if (context->hidden.windowsio.buffer.left) {
SetFilePointer(context->hidden.windowsio.h,
-(LONG)context->hidden.windowsio.buffer.left, NULL,
FILE_CURRENT);
context->hidden.windowsio.buffer.left = 0;
}
/* if in append mode, we must go to the EOF before write */
if (context->hidden.windowsio.append) {
if (SetFilePointer(context->hidden.windowsio.h, 0L, NULL, FILE_END) ==
INVALID_SET_FILE_POINTER) {
SDL_Error(SDL_EFWRITE);
return 0;
}
}
if (!WriteFile
(context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) {
SDL_Error(SDL_EFWRITE);
return 0;
}
nwritten = byte_written / size;
return nwritten;
}
答案 0 :(得分:0)
简而言之:我设法改进了它。现在我的 0.316382秒 ,这比其他解决方案慢一点。
但这是我生命中最糟糕的黑客之一。我很欣赏任何更好的解决方案。
如何完成:我已为SDL_RWFromFile()
滚动自定义替换:我已从SDL_rwops.c
复制粘贴实施并删除了所有预处理器分支,就好像仅{{1}已定义。该函数包含对HAVE_STDIO_H
的调用,因此我也复制了粘贴SDL_RWFromFP()
并对其应用了相同的修改。反过来,SDL_RWFromFP()
依赖于SDL_RWFromFP()
,stdio_size()
,stdio_read()
,stdio_write()
和stdio_seek()
(这些是stdio_close()
的一部分因此,我也复制粘贴了它们。反过来,这些依赖于(再次!)某些领域的隐藏&#34; SDL_rwops.c
内部的联合,在使用预处理器的窗口上禁用。我没有更改标题,而是更改了复制粘贴的代码,以使用&#34;隐藏&#34;的不同的成员。联合,做存在于Windows上。 (这是安全的,因为除了我自己的和复制粘贴的代码之外什么也没有触及结构。)还做了一些其他调整,使代码可以用作C ++而不是C语言。
这就是我得到的:
struct SDL_RWops