Gor*_*ley 7 python gtk performance gobject
我有一个带有GTK(GObject)界面的脚本,我用它来发布到我的照片博客.
我试图通过在后台线程中加载图像来提高它的响应能力.
我没有运气试图从后台线程填充GdkPixbuf对象,我尝试过的所有东西都是坚固的.
所以作为替代,我以为我会在后台线程中读取文件,然后按需将它们推送到GdkPixbuf中.这种方法产生了一些令人惊讶且相当令人沮丧的表现结果,让我想知道我是否做了一些非常错误的事情.
我正在玩相机上轻微压缩的jpegs,它们往往大约是3.8mb.
这是原始的阻塞图像加载:
pb = GdkPixbuf.Pixbuf.new_from_file(image_file)
Run Code Online (Sandbox Code Playgroud)
这个平均大约550毫秒,不是很大,但如果你想浏览十几张图片,那就相当乏味了.
然后我将它拆分,这是文件读取:
data = bytearray(open(self.image_file).read())
Run Code Online (Sandbox Code Playgroud)
这平均为15毫秒,这真的很好,但也有点令人担心,如果我们能在15毫秒内读取文件,那么花费的其他535毫秒是什么?
顺便说一句,存在bytearray调用,因为PixBufLoader不会接受数据.
然后是Pixbuf加载:
pbl = GdkPixbuf.PixbufLoader()
pbl.write(data, len(data))
pbl.close()
pb = pbl.get_pixbuf()
Run Code Online (Sandbox Code Playgroud)
平均大约1400毫秒,这比让Gtk完成所有工作的时间长近3倍.
我在这里做错了吗?
我的猜测:你做错了什么。我刚刚将 libjpeg-turbo 与 gdk.PixbufLoader 进行了比较,发现速度几乎没有差异。我使用的代码如下。
对于 libjpeg-turbo (jpegload.c):
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <jpeglib.h>
void decompress(FILE* fd)
{
JSAMPARRAY buffer;
int row_stride;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, fd);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
row_stride = cinfo.output_width * cinfo.output_components;
buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
while (cinfo.output_scanline < cinfo.output_height) {
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
}
int main(int argc, char** argv)
{
long len;
FILE *fd;
unsigned char *buf;
struct timeval start, end;
int i;
const int N = 100;
int delta;
/* read file to cache it in memory */
assert(argc == 2);
fd = fopen(argv[1], "rb");
fseek(fd, 0, SEEK_END);
len = ftell(fd);
rewind(fd);
buf = malloc(len);
assert(buf != NULL);
assert(fread(buf, 1, len, fd) == len);
gettimeofday(&start, NULL);
for(i = 0; i < N; i++) {
rewind(fd);
decompress(fd);
}
gettimeofday(&end, NULL);
if(end.tv_sec > start.tv_sec) {
delta = (end.tv_sec - start.tv_sec - 1) * 1000;
end.tv_usec += 1000000;
}
delta += (end.tv_usec - start.tv_usec) / 1000;
printf("time spent in decompression: %d msec\n",
delta/N);
}
Run Code Online (Sandbox Code Playgroud)
对于 python gdk (gdk_load.py):
import sys
import gtk
import time
def decompress(data):
pbl = gtk.gdk.PixbufLoader()
pbl.write(data, len(data))
pbl.close()
return pbl.get_pixbuf()
data = open(sys.argv[1]).read()
N = 100
start = time.time()
for i in xrange(N):
decompress(data)
end = time.time()
print "time spent in decompression: %d msec" % int((end - start) * 1000 / N)
Run Code Online (Sandbox Code Playgroud)
测试运行结果:
$ gcc jpegload.c -ljpeg
$ ./a.out DSC_8450.JPG
time spent in decompression: 75 msec
$ python gdk_load.py DSC_8450.JPG
time spent in decompression: 75 msec
$ identify DSC_8450.JPG
DSC_8450.JPG JPEG 3008x2000 3008x2000+0+0 8-bit DirectClass 2.626MB 0.000u 0:00.019
Run Code Online (Sandbox Code Playgroud)
编辑:另一个测试,使用gi.repostiroy这个时间:
import sys
import time
from gi.repository import GdkPixbuf
def decompress(filename):
pb = GdkPixbuf.Pixbuf.new_from_file(filename)
return pb
N = 100
start = time.time()
for i in xrange(N):
decompress(sys.argv[1])
end = time.time()
print "time spent in decompression: %d msec" % int((end - start) * 1000 / N)
Run Code Online (Sandbox Code Playgroud)
和结果:
$ python gi_load.py DSC_8450.JPG
time spent in decompression: 74 msec
Run Code Online (Sandbox Code Playgroud)
使用 gi.repository 的 GdkPixbuf.PixbufLoader 确实比“纯”慢得多gtk.gdk。代码:
import sys
import time
from gi.repository import GdkPixbuf
def decompress(data):
pbl = GdkPixbuf.PixbufLoader()
pbl.write(data, len(data))
pbl.close()
return pbl.get_pixbuf()
data = bytearray(open(sys.argv[1]).read())
N = 100
start = time.time()
for i in xrange(N):
decompress(data)
end = time.time()
print "time spent in decompression: %d msec" % int((end - start) * 1000 / N)
Run Code Online (Sandbox Code Playgroud)
结果:
$ python gi_load.py DSC_8450.JPG
time spent in decompression: 412 msec
Run Code Online (Sandbox Code Playgroud)
但GdkPixbuf.Pixbuf.new_from_file即使使用 ,其工作速度也与纯 C 版本一样快gi.repository,因此您仍然要么做错了什么,要么期望太多。
| 归档时间: |
|
| 查看次数: |
759 次 |
| 最近记录: |