我正在开发一个需要复杂的 Photoshop 类型混合效果的项目。我正在使用自定义 RenderScript
脚本来解决这个问题。
我一直在运行 Kitkat 的 Samsung Galaxy S4
设备上对其进行测试,一切都运行良好且速度非常快。
然后我尝试在运行 Lollipop 的 Nexus 5 上测试它,我注意到性能突然下降。
我开始对代码中的各个部分进行计时,以查看哪些部分速度变慢,并得出以下结论:
Allocation.createFromBitmap
- Runtime on Kitkat - ~5-10 millisec
- Runtime on Lollipop - ~100-150 millisec
mRenderScript.destory()
- Runtime on Kitkat - ~1-3 millisec
- Runtime on Lollipop - ~60-100 millisec
我很好奇为什么在本应更强大的设备上创建 Allocation
对象和销毁 RenderScript
对象时性能会突然下降,而在应该更高级的操作系统。
我可以针对 API 21 操作系统做些什么来使这些方法运行得更快吗?
有没有人遇到过这个问题或者可以重现它?
我应该注意到脚本的实际运行(即 ScriptC.forEach
方法)在两个设备/操作系统上运行得非常快。此外,我使用的是原生 RenderScript
API,而不是任何支持库。
如有任何意见,我们将不胜感激。
编辑:
我在这里复制了 Github 中 Androids Lollipop-release 源代码的相关行 Allocation.java
static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
}
return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
USAGE_GRAPHICS_TEXTURE);
}
注意当目标 SDK 高于 17 时,Allocation 是如何默认使用 USAGE_SHARED
标志创建的。可能是这些额外的标志导致了问题吗?我应该改用 USAGE_GRAPHICS_TEXTURE
标志吗?
编辑2
正在关注 R. Jason Sam的建议,当 Nexus 5 连接到我的计算机时,我运行了以下脚本:
adb shell setprop debug.rs.default-CPU-driver 1
在此之后,上述函数的运行时间明显加快(分别为 ~30-40 毫秒和 20-50 毫秒)。仍然不如 Lollipop 之前的设备那么快,但在可接受的性能范围内。
我对这个解决方案的唯一问题是,除非我不理解某些东西,否则它不能被视为解决方案,因为它需要我在每个有问题的设备上调用这个脚本,然后才能在其上运行应用程序。
我可以在我的代码中做些什么来模拟这个 adb 调用吗?
最终编辑
好吧,这个问题似乎源于我每次调用使用 RenderScript 执行混合效果的函数时都在创建一个新的 RenderScript 对象。
我做了一些代码重构,现在,我不再在每次调用 effect 方法时都创建一个新的 RenderScript 对象,而是每次都重复使用同一个对象。在 Lollipop 设备上创建 RenderScript 对象的第一次创建仍然需要更长的时间,但现在问题得到缓解,因为我继续在多个方法调用中重复使用相同的对象。
我会将其添加为答案。
最佳答案
问题似乎源于这样一个事实,即每次调用使用 RenderScript
执行混合效果的函数时,我都在创建一个新的 RenderScript
对象。
我做了一些代码重构,现在,我不再在每次调用 effect 方法时创建一个新的 RenderScript
对象,而是每次都重复使用相同的对象。 RenderScript
对象的第一次创建在 Lollipop 设备上创建仍然需要更长的时间,但现在问题得到缓解,因为我继续在多个方法调用中重复使用相同的对象。
一旦我确定我不再需要它以确保没有内存泄漏,我一定会在共享的 RenderScript
对象上调用 destory()
。
根据 this帖子,似乎重用 RenderScript
对象而不是每次都创建一个新对象是公平的做法,但我很高兴听到其他人关于他们在这件事上的经验的意见。遗憾的是,网上没有太多关于这个主题的文档,但到目前为止,一切似乎都在多个设备/操作系统上运行良好。
关于java - Android - RenderScript - SDK 21 中的性能下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28750267/