python 和 gobject 的图像加载性能问题
我有一个带有 GTK(GObject) 接口的脚本,用于发布到我的照片博客。
我试图通过在后台线程中加载图像来提高它的响应能力。
我没有运气尝试从后台线程填充 GdkPixbuf 对象,我尝试过的所有内容都卡住了。
因此,作为替代方案,我认为我应该在后台线程中读取文件,然后根据需要将它们推送到 GdkPixbuf 中。这种方法产生了一些令人惊讶且相当令人沮丧的性能结果,这让我怀疑我是否做错了什么。
我正在使用相机上的轻微压缩的 jpeg,它们通常约为 3.8mb。
这是原始的阻塞图像加载:
pb = GdkPixbuf.Pixbuf.new_from_file(image_file)
平均大约 550 毫秒,不算长,但如果您想浏览十几张图像,则相当乏味。
然后我把它分开,这是读取的文件:
data = bytearray(open(self.image_file).read())
平均需要 15 毫秒,这确实很好,但也有点令人担忧,如果我们可以在 15 毫秒内读取文件,那么剩下的 535 毫秒花在了什么上?
顺便说一句,字节数组调用存在,因为否则 PixBufLoader 不会接受数据。
然后是 Pixbuf 加载:
pbl = GdkPixbuf.PixbufLoader()
pbl.write(data, len(data))
pbl.close()
pb = pbl.get_pixbuf()
平均需要 1400 毫秒左右,这比让 Gtk 完成这一切要长近 3 倍。
我在这里做错了什么吗?
I have a script with a GTK(GObject) interface I use for posting to my photo blog.
I'm trying to improve it's responsiveness by loading the images in a background thread.
I've had no luck trying to populate GdkPixbuf objects from a background thread, everything I've tried just jams solid.
So as an alternate I thought I'd read the files in the background thread and then push them into GdkPixbuf's on demand. This approach has yielded some surprising and rather depressing performance results which make me wonder if I'm doing something grossly wrong.
I'm playing with lightly compressed jpegs off my camera, they tend to be around 3.8mb.
Here's the original blocking image load:
pb = GdkPixbuf.Pixbuf.new_from_file(image_file)
This averages about 550ms, not huge, but rather tedious if you want to flick through a dozen images.
Then I split it up, here's the file read:
data = bytearray(open(self.image_file).read())
This averages 15ms, that's really nice, but also kinda worrying, if we can read the file in 15ms what are the other 535ms being spent on?
Incidentally the bytearray call exists because the PixBufLoader wouldn't accept the data otherwise.
And then the Pixbuf load:
pbl = GdkPixbuf.PixbufLoader()
pbl.write(data, len(data))
pbl.close()
pb = pbl.get_pixbuf()
This averages around 1400ms, which is nearly 3 times longer than letting Gtk do it all.
Am I doing something wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我的猜测:你做错了什么。我刚刚将 libjpeg-turbo 与 gdk.PixbufLoader 进行了比较,发现速度几乎没有差异。我使用的代码如下。
对于 libjpeg-turbo (jpegload.c):
对于 python gdk (gdk_load.py):
测试运行结果:
编辑: 和另一个测试,这次使用 gi.repostiroy:
结果:
GdkPixbuf.PixbufLoader使用 gi.repository 确实比“纯”gtk.gdk 慢得多。代码:
结果:
但是即使使用
gi.repository
,GdkPixbuf.Pixbuf.new_from_file
的工作速度也与纯C版本一样快,所以你仍然要么做错了什么,要么期望太多。My guess: you are doing something wrong. I've just compared libjpeg-turbo with gdk.PixbufLoader and found virtually no speed differences. The code I used is below.
For the libjpeg-turbo (jpegload.c):
For python gdk (gdk_load.py):
Test run results:
EDIT: and another test, using
gi.repostiroy
this time:And results:
GdkPixbuf.PixbufLoader using gi.repository is really much MUCH slower then "pure"
gtk.gdk
. Code:Results:
But
GdkPixbuf.Pixbuf.new_from_file
works as fast as pure C version even usinggi.repository
, so you are still either doing something wrong, or expecting too much.我用 pygtk 开发了一个小型图像查看器。我使用 PixbufLoader,但每次 write() 只输入 N 个字节。与idle_add() 结合使用,我可以在后台加载图像,同时应用程序仍然响应用户输入。
这是来源:http://guettli.sourceforge.net/gthumpy/src/ImageCache。 py
I have developed a small image viewer with pygtk. I use PixbufLoader, but I feed only N bytes per write(). In combination with idle_add() I can load an image in background, while the application still responses to user input.
Here is the source: http://guettli.sourceforge.net/gthumpy/src/ImageCache.py