APNG4Android
APNG4Android copied to clipboard
gif加载性能
你好,我有一个疑问,glide默认有gif加载功能,该库提供的gif加载方式相比glide默认的gif加载有性能上的优势吗?
glide gif解析是在java层,本库gif解析转到native侧,native会比java侧在数据处理上有性能优势
我再补充一些: Glide默认支持Gif解析,但在实际中,发现,当列表中有大量Gif同时播放时,低端的手机很容易会出现卡顿的情况,CPU占用很高. 该库对LZW解压数据这一步进行优化,使用C++代码重新实现了LZW解压算法,并进行了局部优化.性能上是要比原生Glide强的. 当然该库的三个解码器都可以进行逐个控制开启或关闭(APNG,WebP,Gif) 如下代码会禁用该库的Gif解码器(不推荐)
GlideApp.with(imageView)
.load(url)
.set(AnimationDecoderOption.DISABLE_ANIMATION_GIF_DECODER, true)
.into(imageView);
虽然解析gif放到了native层,但是我在实际测试中发现性能比glide自带的还要差,会不会与gifframe处理过程中把数据通过canvas绘制到bitmap,再又将bitmap的数据倒腾到framebuffer中,真正绘制的时候,会再次将数据生成到bitmap有关。
实际测试是怎么测试的呢
用的android studio的 profile工具
这个是使用本库加载gif的性能图CPU部分
这个是默认glide加载同一张gif的的性能图CPU部分
使用本库加载同一个图CPU会降低
这个是使用本库加载gif的性能图内存部分
这个是默认glide加载同一张gif的的性能图内存部分
内存消耗本库略微低一点
使用的是这个gif,43k大小,内存本库会节约几M
用的android studio的 profile工具
能否提供更明确的截图信息和测试方法,这个结论跟我之前测试的结果不符
虽然解析gif放到了native层,但是我在实际测试中发现性能比glide自带的还要差,会不会与gifframe处理过程中把数据通过canvas绘制到bitmap,再又将bitmap的数据倒腾到framebuffer中,真正绘制的时候,会再次将数据生成到bitmap有关。
对于数据的传输,是一个拷贝过程,相对于图片解码整个流程来说影响较小
使用的是这个gif,43k大小,内存本库会节约几M
对于更大或更多的Gif,效果会更明显
我用的图片比较大,为了效果更明显。
加载的图片为下面6张。没张大小都十几兆。
"https://cdn.pokekara.com/sp1/pokekara/gif/large/61/7c/6105f1403478f6e8deefb401394d987c_600-600-1.gif",
"https://cdn.pokekara.com/sp1/pokekara/gif/large/ba/d4/baf131714001c518e47bbc6b9a8a7bd4_600-600-1.gif",
"https://cdn.pokekara.com/sp1/pokekara/gif/large/02/04/029fbb80847025afb926891c11248804_600-600-1.gif",
"https://cdn.pokekara.com/sp1/pokekara/gif/large/a1/44/a1f34d8009839932f99c162fa8dc7444_600-600-1.gif",
"https://cdn.pokekara.com/sp1/pokekara/gif/large/46/3e/46b811d86929b3316c4098ccfddc103e_600-600-1.gif",
"https://cdn.pokekara.com/sp1/pokekara/gif/large/0e/aa/0e1795452a8d69ee8511e5c9830a22aa_600-600-1.gif"
前两张图片是使用本库加载时的cpu和内存。后两张图是使用glide加载时的cpu和内存。
先对比下一张图?控制变量
一张图cpu和内存差别不太大。用小图区别更加不明显。
稍等,我来复现一下你的测试结果.
ok稍后我看下
我用的图片比较大,为了效果更明显。 加载的图片为下面6张。没张大小都十几兆。 "https://cdn.pokekara.com/sp1/pokekara/gif/large/61/7c/6105f1403478f6e8deefb401394d987c_600-600-1.gif", "https://cdn.pokekara.com/sp1/pokekara/gif/large/ba/d4/baf131714001c518e47bbc6b9a8a7bd4_600-600-1.gif", "https://cdn.pokekara.com/sp1/pokekara/gif/large/02/04/029fbb80847025afb926891c11248804_600-600-1.gif", "https://cdn.pokekara.com/sp1/pokekara/gif/large/a1/44/a1f34d8009839932f99c162fa8dc7444_600-600-1.gif", "https://cdn.pokekara.com/sp1/pokekara/gif/large/46/3e/46b811d86929b3316c4098ccfddc103e_600-600-1.gif", "https://cdn.pokekara.com/sp1/pokekara/gif/large/0e/aa/0e1795452a8d69ee8511e5c9830a22aa_600-600-1.gif" 前两张图片是使用本库加载时的cpu和内存。后两张图是使用glide加载时的cpu和内存。
![]()
![]()
![]()
我这边测试下来确实如此,稍等我进一步验证下.
好的 辛苦
在图片较大时,因为数据较大导致native层需要分批调用Reader接口从Java层拿数据,导致JNI调用次数急剧攀升,用于测试的图片每一帧都有数千次JNI的调用,JNI开销导致整体方法性能迅速劣化.
目前建议该情况先通过设置AnimationDecoderOption.DISABLE_ANIMATION_GIF_DECODER
避免该情况.
我会继续跟进,感谢反馈该问题.
好的 谢谢。
我再补充一些: Glide默认支持Gif解析,但在实际中,发现,当列表中有大量Gif同时播放时,低端的手机很容易会出现卡顿的情况,CPU占用很高. 该库对LZW解压数据这一步进行优化,使用C++代码重新实现了LZW解压算法,并进行了局部优化.性能上是要比原生Glide强的. 当然该库的三个解码器都可以进行逐个控制开启或关闭(APNG,WebP,Gif) 如下代码会禁用该库的Gif解码器(不推荐)
GlideApp.with(imageView) .load(url) .set(AnimationDecoderOption.DISABLE_ANIMATION_GIF_DECODER, true) .into(imageView);
你们只是把解析放在了native层,但是当gif解析成一张张的bitmap后,这些bitmap的解析并没有放在native层。
我再补充一些: Glide默认支持Gif解析,但在实际中,发现,当列表中有大量Gif同时播放时,低端的手机很容易会出现卡顿的情况,CPU占用很高. 该库对LZW解压数据这一步进行优化,使用C++代码重新实现了LZW解压算法,并进行了局部优化.性能上是要比原生Glide强的. 当然该库的三个解码器都可以进行逐个控制开启或关闭(APNG,WebP,Gif) 如下代码会禁用该库的Gif解码器(不推荐)
GlideApp.with(imageView) .load(url) .set(AnimationDecoderOption.DISABLE_ANIMATION_GIF_DECODER, true) .into(imageView);
你们只是把解析放在了native层,但是当gif解析成一张张的bitmap后,这些bitmap的解析并没有放在native层。
不明白你说的bitmap的解析是什么东西, bitmap就是像素点的集合,不需要什么解析,这也不是性能的瓶颈点
我再补充一些: Glide默认支持Gif解析,但在实际中,发现,当列表中有大量Gif同时播放时,低端的手机很容易会出现卡顿的情况,CPU占用很高. 该库对LZW解压数据这一步进行优化,使用C++代码重新实现了LZW解压算法,并进行了局部优化.性能上是要比原生Glide强的. 当然该库的三个解码器都可以进行逐个控制开启或关闭(APNG,WebP,Gif) 如下代码会禁用该库的Gif解码器(不推荐)
GlideApp.with(imageView) .load(url) .set(AnimationDecoderOption.DISABLE_ANIMATION_GIF_DECODER, true) .into(imageView);
你们只是把解析放在了native层,但是当gif解析成一张张的bitmap后,这些bitmap的解析并没有放在native层。
不明白你说的bitmap的解析是什么东西, bitmap就是像素点的集合,不需要什么解析,这也不是性能的瓶颈点
gif是被解析成一张张的bitmap绘制在屏幕上的,解析这些bitmap的时候你们是放在哪解析的,还是说你们用的giflib?
Glide默认支持gif开销最大的不是在解析的过程,而是在生成一张张bitmap,而且在ImageView在显示一张bitmap的同时已经生成了下一张bitmap放在内存里,所以glide默认的gif加载内存才会居高不下