java - Android - RenderScript - SDK 21 中的性能下降

标签 java android renderscript

我正在开发一个需要复杂的 Photoshop 类型混合效果的项目。我正在使用自定义 RenderScript 脚本来解决这个问题。

我一直在运行 KitkatSamsung Galaxy S4 设备上对其进行测试,一切都运行良好且速度非常快。

然后我尝试在运行 LollipopNexus 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/

相关文章:

android - 如何在 renderscript 和 android 框架之间交换数据?

java - Play Framework : load javascript only on specific method calls

java - 下载多个文件 Java

android - 使用 Phonegap 时是否需要 AndroidManifest.xml?

android - Proguard 混淆和渲染脚本

java - android studio 0.2.2 上的 renderscript 错误

java - 具有固定原点的图形

java - 将 `java.sql.blob` 转换为 `javax.xml.transform.stream.StreamSource`

android - 相册缩略图名称是如何制作的?

Android 选项卡按钮 : handle tap/click event