[✔️]cocos2dx Tiledmap性能优化分析:layer data建议使用压缩格式gzip/zlib

简介: [✔️]cocos2dx Tiledmap性能优化分析:layer data建议使用压缩格式gzip/zlib

项目中有一个tmx文件,16M,加载这个tiledmap的时候,非常慢非常慢,在VisualStudio中通过性能探查器,进行了一波分析:


image.png


从饼状图中可以看到性能压力集中在文件IO上,追查到性能热点代码,是在解析csv数据:


unsigned char *buffer;
TMXLayerInfo* layer = tmxMapInfo->getLayers().back();
tmxMapInfo->setStoringCharacters(false);
std::string currentString = tmxMapInfo->getCurrentString();
vector<string> gidTokens;
istringstream filestr(currentString);
string sRow;
// 因为地图是1000*1000,好在csv数据只有一行,所以这里只会执行一次
while(getline(filestr, sRow, '\n')) {
    string sGID;
    istringstream rowstr(sRow);
    // 但是因为csv是通过,分割,所以间接导致gidTokens会非常的大
    // 性能热点函数getline
    while (getline(rowstr, sGID, ',')) {
        gidTokens.push_back(sGID);
    }
}
// 32-bits per gid
buffer = (unsigned char*)malloc(gidTokens.size() * 4);
if (!buffer)
{
    CCLOG("cocos2d: TiledMap: CSV buffer not allocated.");
    return;
}
uint32_t* bufferPtr = reinterpret_cast<uint32_t*>(buffer);
// 这里是百万次以上循环,有一定的性能压力
for(auto gidToken : gidTokens) {
    auto tileGid = (uint32_t)strtoul(gidToken.c_str(), nullptr, 10);
    *bufferPtr = tileGid;
    bufferPtr++;
}
layer->_tiles = reinterpret_cast<uint32_t*>(buffer);
tmxMapInfo->setCurrentString("");


getline 是 C++ 标准库中的一个函数,其作用是从输入流中读取一行数据并存储到指定的字符串对象中。


std::istream& getline(std::istream& is, std::string& str, char delim);


其中,is 表示输入流对象,str 表示要存储读取结果的字符串对象,delim 表示分隔符(默认为换行符 \n)。当遇到分隔符时,getline 函数会停止读取并返回流对象。该函数会忽略分隔符本身,并将其从输入流缓冲区中删除。


getline 函数在输入流中读取一行数据时,需要逐个字符地读取,并检查每个字符是否为分隔符。由于字符的读取和检查是严格按照顺序进行的,因此这种方法会导致在处理大量数据时的性能问题。


不同encoding对比


encoding 第1次/第2次 size
csv 21812ms/21508ms 16.2M
base64 1670ms /610ms 42.1M
zlib 1183ms/105ms 471K
gzip 1189ms/130ms 472k


以上是测试超大tiledmap地图的加载性能报告,观察到一个非常有趣的现象,zlib的第1次加载和第2次加载耗费的时间差距有点大,初步猜测是因为加载纹理导致的


  • 第1次加载时,可以看到在addImage上花费了大量时间


image.png


  • 第2次加载时,在xml解析上花费了大量时间:


image.png


这个结果是符合我们的猜测,所以如果要加快tmx的创建,可以预加载tmx所使用的纹理图片。


结论


超大地图,尽量保存采用zlib、gzip的方式保存数据,会降低IO操作,提高tiledmap的性能,同时减少tmx文件大小,理论上这个问题在cocos creator中也会遇到。


目录
相关文章
|
5月前
|
Python
Python 压缩PDF减小文件大小
【8月更文挑战第6天】介绍了三种用Python压缩PDF文件的方法:1) 使用`pdfcompressor`库,安装后可通过简单命令压缩文件;2) 利用`PyPDF2`库,需手动设置压缩参数;3) 采用`pdfsizeopt`库,一键优化PDF大小。各方法均提供示例代码,便于快速实现文件压缩。
738 0
|
2月前
|
存储 算法 Ubuntu
你可能不知道 xz 也是一种压缩格式,并且还相当惊艳
在现代计算中,文件压缩是节省存储空间和提高传输效率的关键技术。Linux 提供了多种压缩工具,如 `tar`、`zip`、`gzip`、`bzip2` 和 `xz`。本文重点介绍 `xz` 命令,探讨其高压缩比的优势及其基本用法,适合编程新手学习。
69 4
|
6月前
|
Python
gzip模块概述
gzip模块概述
|
8月前
|
存储 算法 Linux
Gzip的压缩级别有哪些选择?
【4月更文挑战第29天】Gzip的压缩级别有哪些选择?
340 1
|
8月前
|
存储 算法 Linux
Gzip的压缩级别
【4月更文挑战第29天】压缩级别
501 1
|
Python
Python--另一个压缩模块(好用)
Python--另一个压缩模块(好用)
65 0
|
JavaScript 区块链
项目性能优化之用url-loader把小图片转base64,大图片使用image-webpack-loader压缩
项目性能优化之用url-loader把小图片转base64,大图片使用image-webpack-loader压缩
379 0
|
算法 JavaScript 前端开发
Node侧实现内容压缩(gzip/br/deflate)介绍与实践
Node侧实现内容压缩(gzip/br/deflate)介绍与实践
|
Web App开发 算法 前端开发
JavaWeb - 简单聊聊 GZIP 的压缩原理与日常应用
JavaWeb - 简单聊聊 GZIP 的压缩原理与日常应用
413 0
JavaWeb - 简单聊聊 GZIP 的压缩原理与日常应用
|
JavaScript 算法 前端开发
VuePress 博客优化之开启 Gzip 压缩
在 《一篇带你用 VuePress + Github Pages 搭建博客》中,我们使用 VuePress 搭建了一个博客,在 《一篇从购买服务器到部署博客代码的详细教程》中,我们将代码部署到服务器上,最终的效果查看:TypeScript 中文文档。今天我们来学习如何开启服务器的 Gzip 压缩。
325 0
VuePress 博客优化之开启 Gzip 压缩

热门文章

最新文章