我正在制作涉及pycurl的东西,因为pycurl依赖于libcurl,我正在阅读它的文档并遇到了这个Multi接口,您可以使用单个多对象执行多次传输。我想知道这是否比具有多个简单接口更快/更高的内存效率?我想知道这种方法有什么优势,因为该网站几乎没有说,
"在同一个线程中启用多个同时传输,而不会使应用程序变得复杂。"
答案 0 :(得分:2)
你正试图优化一些无关紧要的东西。
如果您想尽快下载200个网址,您将花费99.99%的时间等待这200个请求,受网络和/或您下载的服务器的限制。优化的关键是制作正确数量的并发请求。你可以采取的任何措施来减少最后的0.01%对你的程序没有明显的影响。 (见Amdahl's Law。)
不同的来源提供不同的指导方针,但通常它介于6-12个请求之间,不超过2-4个同一服务器。由于你是从谷歌那里拿出来的,我建议你开始4个并发请求,然后,如果这还不够快,可以调整这个数字,直到你得到最好的结果。
至于空间,存储200页的成本远远超过了几十个字节的成本。同样,你要优化的是那200页 - 通过将它们存储到磁盘而不是存储器中,通过在它们进入时解析它们而不是下载所有内容然后解析所有内容等。
无论如何,不是查看您拥有的命令行工具并尝试查找与其类似的库,而是直接查找库。 pycurl
在某些情况下可能很有用,例如,当您尝试执行复杂的操作并且您已经知道如何使用libcurl
时,但通常情况下,它会更容易使用像urllib
这样的stdlib模块或像requests
那样尽可能简单的第三方模块。
文档中的main example for ThreadPoolExecutor
显示了如何完成您想要做的事情。 (如果您使用的是Python 2.x,则必须pip install futures
获取ThreadPoolExecutor
的后端,并使用urllib2
代替urllib.request
,否则代码将完全相同。)
答案 1 :(得分:1)
在同一个线程中同时运行多个简单接口意味着构建自己的反应器并在较低级别驱动卷曲。这在C中是痛苦的,在Python中同样令人痛苦,这就是为什么libcurl
提供并推荐多个。
但是那个"在同一个线程中#34;关键在这里。您还可以创建一个线程池并将简单实例放入其中。在C中,这仍然是痛苦的;在Python中,它很简单。事实上,使用concurrent.futures.ThreadPoolExecutor
的文档中的第一个示例做了类似的事情,但实际上比您需要的更复杂,而且它仍然只是几行代码。
如果您使用手动反应器比较多重与简单,简单是主要的好处。在C中,您可以轻松实现比libcurl
使用的更高效的反应堆;在Python中,这可能是也可能不是。但在任何一种语言中,与您正在做的其他事情相比,在少数几个网络请求之间切换的性能成本将会非常小 - 尤其是等待那些网络请求 - 它不太可能重要
如果您要将多线程与简单线程池进行比较,那么反应堆绝对可以胜过线程(除了可以将线程池绑定到预控器的平台上,就像Windows I / O完成端口一样) ,特别是对于大量的并发连接。此外,每个线程都需要自己的堆栈,这通常意味着分配大约1MB的内存页(虽然不是全部使用),这对于大量连接的32位域来说可能是一个严重的问题。这就是为什么很少有严肃的服务器使用线程进行连接的原因。但是在客户中建立一些联系,这一切都不重要;再次,浪费8个线程而不是使用反应堆所产生的成本与你的计划的实际成本相比将是如此之小,以至于它们无关紧要。