gpt4 book ai didi

python - 协调Python Aggdraw中的容器类型以获得最快的渲染速度?

转载 作者:太空宇宙 更新时间:2023-11-03 18:39:23 24 4
gpt4 key购买 nike

原始问题:

我对Aggdraw文档中找不到有关Python Aggdraw模块的问题。我正在使用“ .polygon”命令,该命令在图像对象上渲染多边形并将输入坐标作为其参数。

我的问题是,是否有人知道xy坐标可以位于哪种类型的序列容器中(列表,元组,生成器,itertools-generator,数组,numpy数组,双端队列等)或具有经验,最重要的是哪种输入类型将帮助Aggdraw以最快的方式渲染图像?

文档只提到多边形方法采用:“ Python序列(x,y,x,y,…)”

我认为Aggdraw对某些序列类型的优化要比对其他序列类型的优化更多,和/或某些序列类型必须先进行转换,因此某些类型的速度将比其他类型更快。因此,也许有人从理论上或经验上知道了有关Aggdraw内部运作的这些细节?

我已经进行了一些初步的测试,并且很快就会做更多,但是我仍然想知道为什么一个选项可能更快的背后的理论,因为这可能是因为我没有正确地进行测试,或者还有一些其他方法可以优化Aggdraw我不知道的渲染。

(顺便说一句,这似乎是微不足道的优化,但是当目标是能够快速渲染成千上万的多边形并能够放大和缩小它们时,这并不是一个简单的优化。因此,对于这个问题,我不希望有其他渲染模块的建议(从我的测试来看,Aggdraw似乎是最快的之一。我也知道还有其他优化瓶颈,例如坐标到像素的转换等,但目前我只关注Aggdraw内部渲染速度的最后一步。)

非常感谢一群好奇地了解Aggdraw有哪些知识和经验的人。



赢家?初步测试

现在,我进行了一些初步测试,并在页面下方的“答案”中报告了结果(如果需要详细信息)。主要发现是将浮点坐标四舍五入为像素坐标,并将其放入数组中是使Aggdraw渲染图像或地图的最快方法,并以可比较的速度实现了令人难以置信的650%的快速渲染加速使用著名的和常用的GIS软件。剩下的就是找到快速的方法来优化坐标转换和shapefile加载,这些确实是艰巨的任务。对于所有发现,请查看页面下方的我的答案帖子。

我仍然想听听您是否进行了任何测试,或者是否还有其他有用的答案或意见。如果有人知道,我仍然对红利问题的答案感到好奇。



奖励问题:

如果您不知道此问题的具体答案,那么如果您知道实际的Aggdraw渲染使用哪种编程语言,还是有帮助的?我已经读过Aggdraw模块只是原始C ++ Anti-Grain Geometry库的Python绑定,但并不完全确定这实际上意味着什么。这是否意味着Aggdraw Python命令只是访问和激活“幕后” c ++库的一种方式,以便实际渲染以C ++和C ++速度进行?如果是这样,那么我猜想C ++必须将Python序列转换为C ++序列,而优化将是找出哪个Python序列可以最快地转换为C ++序列。还是Aggdraw模块仅仅是用纯Python重写的原始库(因此比C ++版本慢得多)?如果是这样,它支持哪种Python类型,以及哪种类型的渲染工作更快。 enter code here

最佳答案

赢家?初步测试

这是我最初测试的结果,这些测试用于aggdraw渲染的输入类型更快。在aggdraw文档中可以找到一个线索,其中说aggdraw.polygon()仅采用“序列”:正式定义为“ str,unicode,list,元组,字节数组,缓冲区,xrange”(http://docs.python.org/2/library/stdtypes.html)。幸运的是,我发现aggdraw渲染还接受其他输入类型。经过一些测试之后,我想出了一个输入容器类型的列表,我可以发现该容器支持aggdraw(也许还有PIL)渲染:


元组
清单
数组
numpy数组
双端队列


不幸的是,当提供以下内容中包含的坐标时,aggdraw不支持并导致错误:


发电机
itertool生成器

词典


然后进行性能测试!测试多边形是来自全球次国家级省界的全球管理单位数据库中的20000个(多)多边形的子集,并使用PyShp shapefile阅读器模块(http://code.google.com/p/pyshp/)加载到内存中。为了确保测试仅测量aggdraw的内部渲染速度,我确保仅在将多边形坐标转换为aggdraw图像像素坐标之后,并且在创建具有正确输入类型和aggdraw的输入参数列表之后,才启动计时器。笔和.Brush对象。然后,我使用带有预加载的坐标和参数的itertools.starmap计时并运行渲染:

t=time.time()
iterat = itertools.starmap(draw.polygon, args) #draw is the aggdraw.Draw() object
for runfunc in iterat: #iterating through the itertools generator consumes and runs it
pass
print time.time()-t


我的发现证实了传统的观念,即元组和数组是最快的Python迭代器,而两者最终都是最快的。列表的速度要慢大约50%,而numpy数组的速度也要慢(考虑到Numpy数组的速度,这最初令人惊讶,但是后来我读到Numpy数组只有在使用内部Numpy函数时才很快,对于普通的Python迭代,它们通常比其他类型的慢)。通常被认为是最快的双端队列(Deques)是最慢的(几乎100%,即慢2倍)。

### Coordinates as FLOATS
### Pure rendering time (seconds) for 20 000 polygons from the GADM dataset
tuples
8.90130587328
arrays
9.03419164657
lists
13.424952522
numpy
13.1880489246
deque
16.8887938784


换句话说,如果您通常将列表用于aggdraw坐标,则应该知道通过将它们放入元组或数组中可以将性能提高50%。这不是最根本的改进,但仍然有用且易于实施。

可是等等!我确实找到了另一种方法来从aggdraw模块中挤出更多的性能-实际上很多。我忘记了为什么这样做,但是当我尝试将转换后的浮点坐标舍入为最接近的像素整数作为整数类型(即“ int(round(eachcoordinate))”)时,渲染它们之前,我得到了6.5倍的渲染速度(650%)与最常见的列表容器相比-物有所值且易于优化。令人惊讶的是,当渲染器不必担心舍入数时,数组容器类型的结果比元组快25%。这种预舍入不会丢失我能看到的视觉细节,因为这些浮点无论如何只能分配给一个像素,这可能是为什么在将坐标发送给aggdraw渲染器之前预转换/预舍入坐标可以加快处理速度的原因公元前然后aggdraw不必。一个潜在的警告是,删除十进制信息可能会改变aggdraw进行抗锯齿的方式,但在我看来,最终地图仍然看起来同样抗锯齿且平滑。最后,必须将舍入优化与在Python中舍入数字所花费的时间进行权衡,但是从我的眼中可以看出,进行预舍入所花费的时间并没有超过渲染加速所带来的好处。应该探索进一步的优化方法,以了解如何快速舍入和转换坐标。

### Coordinates as INTEGERS (rounded to pixels)
### Pure rendering time (seconds) for 20 000 polygons from the GADM dataset
arrays
1.40970077294
tuples
2.19892537074
lists
6.70839555276
numpy
6.47806400659
deque
7.57472232757


总而言之,当为aggdraw(可能还有PIL?)提供绘制坐标时,数组和元组是使用最快的容器类型。

鉴于在使用正确的输入类型和aggdraw时可以获得巨大的渲染速度,因此对于地图渲染过程的其他方面(例如坐标转换例程)(即使我已经在探索和例如发现Numpy在这种情况下特别快)。

从所有这些中得出的更普遍的发现是,Python可以潜在地用于非常快速的地图渲染应用程序,从而进一步为Python地理空间脚本开辟了可能性。例如从理论上讲,可以在大约1.5 * 10 = 15秒内渲染20万多个省的整个GADM数据集,而无需考虑坐标到图像坐标的转换,这比QGIS更快,甚至比以我的经验在显示GADM数据集方面遇到困难的ArcGIS还要快。

所有结果均使用Python 2.6.5在具有2年历史的Windows 7老机器上的8核处理器上获得。这些结果在加载和/或处理数据时是否也最有效,这是一个必须测试并在另一篇文章中回答的问题。听到别人在这些方面是否已有很好的见识会很有趣。

关于python - 协调Python Aggdraw中的容器类型以获得最快的渲染速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20874537/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com