重要:同样一个项目,在web 和安卓(模拟器、原生)上运行,性能差距巨大!!!

出来就能看到效果:
work.rar (180.8 KB)
模拟器,原生:

WEB:

模拟器、包括在安卓真机上测试,性能都低得要命,但是WEB端证明了游戏性能OK滴(完成30帧渲染仅需300毫秒)

不知是啥原因,但足以证明是引擎问题,望官方引起重视!

模拟器有啥好比的,要比用真机好不

安卓真机的性能会在 1.6 大幅度优化,1.7 也会有提升

1赞

如果是大量创建对象的用例,在 1.5 及以下版本中都会遇到同性能机型,native 不如 web 的表现,因为我们的绑定层使用的 Spidermonkey 版本过旧,以及绑定代码不够优化导致的。这点在 1.6 中都会得到修复,顺利的话,这两周就会有测试版本,可以尝试一下

1赞

就是用真机,看不懂吗???

我性能还优化啥啊,wev上跑得刚刚滴。

不是说不能优化,但这不是问题啊

我手机骁龙645处理器,不差把,从120帧掉到10帧

这是安卓真机,骁龙645

会优化的,让我们一起呼唤1.6 :)

我在 1.6 中做了更多测试

Mac os x
web: 30 fps,15 ms per frame(实际分辨率 1334750)
native release: 30 fps,30 ms per frame(实际分辨率 1800
1280)

iOS iPhone 7
web:30 fps(实际分辨率 1334750)
native release:7 fps(实际分辨率 2272
1280)

Android 小米4
web:7 fps(实际分辨率 1008568)
native:3 fps(实际分辨率 1920
1080)

这里面有几个变量需要解释一下,native 开启了 retina,并且使用了完整的屏幕像素分辨率,web 上是基于浏览器分辨率开启的 retina,所以填充率上 native 消耗比较大。

不过能看出来你的这个项目,在 web 上还是比 native 更高效一些,我解释一下主要的原因:

  1. 你的项目代码中函数调用损耗特别高,比如每帧都有很多节点(粗略算大概有创建 135 个节点)从 pool 中取出和回收,其中 ms 的一次 _reuse 中有至少 5 次 JSB 函数调用(也就是从 JS 调用 C++),总共大概 700 次。
  2. 每帧 update 的组件数量非常庞大,大概几千个,每个 update 涉及的 JSB 函数调用有两个部分,固定的 move 包含 1 次 JSB 函数调用,可能调用的 _unuse 有至少 4 次 JSB 的函数调用。
  3. 上面说到的分辨率也会导致填充率的增加,进而导致性能不匹配

这样算下来每帧至少会调用几千次 JSB 函数,下面是几个会调用 JSB 函数的例子:

this.node.x = 1; // 包含 1 次 setPositionX 调用
this.node.active = false; // 包含 eventManager.pauseTarget 调用和 actionManager.pauseTarget 调用

这是造成目前 native 慢的主要原因,因为 JSB 的函数调用,是 JS 通过绑定代码调用 C++ 函数,这里面涉及到对象转换,函数调用,所以性能是比 Web 中直接的 JS 调用损耗更高。如果 C++ 函数内的逻辑比较复杂,这种损耗自然就会被 JS 和 C++ 的性能差距抹平,而当调用的函数其实逻辑很简单的时候,JSB 函数调用的损耗就凸显出来了

从项目层规避这些问题是目前最有效的办法。我们也有计划修改目前的绑定层框架,但是需要大概两个主版本的样子

2赞

你应该直接说:自己写一个引擎,自己解决问题最重要

我总结一下,现在问题是,在我游戏里,web性能是原生10倍+,web 性能很好,没问题,原生完全带不动。当然,现在问题已经找到了,现在我想问一问,在所有优化都做完以后(不管是几个版本) ,navie 、特别是安卓平台,能达到或超过web滴表现吗?
另外很感谢 pan大滴回答。

我解释这么多并不是没有意义的,即便是对于游戏开发者,我想告诉大家的是哪里是性能热点。游戏的种类有千千万万,甚至同一个游戏的实现方式也有无数种,不同的实现方式,达到同样的效果,可能性能表现差别巨大。所以游戏项目中必然存在性能优化的过程,即便部分性能问题可能是由引擎,框架,甚至设备本身造成的。真正只关心表现不关心内部实现的只有最终的玩家

4赞

你说得很对,大佬,但你看在不改变玩法滴情况下(极端情况下就是要连续发射那吗多子弹),我这份程序还有可以改进滴地方吗?

具体你目前这种游戏的实现方式,短期内 native 不会提升超过 web 的表现。

我建议的方式是:弹幕使用 Graphics 来渲染,用一个节点挂载上弹幕组件和 Graphics 组件,弹幕组件保存所有弹幕数据,然后在 update 中同步弹幕的信息到 Graphics 组件中让渲染正确。当然,碰撞等自然也是不能用碰撞组件了,需要用弹幕组件中的数据来做计算。

1赞

请问panda是用什么工具测试和查找native的性能热点的? 请推荐一下.

其实对于用户项目,主要是阅读代码和猜测,然后才能相应得去验证,用 log,时间计算,结合 Xcode profiler 之类的工具

收到, 谢谢回复.