A slightly faster slimmer curl
A slightly faster slimmer curl
Back in August I mentioned the new curl performance tests we have running. I figured it could be apt to return to this topic just to mention some of the initial outcomes. When the team gets a new set of charts, graphs and plots that visualize something, like performance, they offer an excellent opportunity for us to try to make them look better. This new setup is no exception. The performance tests have only been running for just a little over two months but they have already made us improve curl performance in several areas. Of course, for most transfers these changes won’t make many visible differences to users. This is more in the vein that every little bit counts and that nothing should run slower than it has to. This is a list of some improvements that are included in the curl 8.23.0 release, to be shipped tomorrow on October 14.
早在八月,我就提到了我们正在运行的全新 curl 性能测试。我觉得现在回到这个话题,谈谈一些初步成果是很恰当的。当团队获得一套能够可视化呈现性能等指标的新图表和曲线图时,这为我们提供了绝佳的机会去尝试优化它们。这次的新设置也不例外。性能测试运行仅两个多月,就已经促使我们在多个领域提升了 curl 的性能。当然,对于大多数传输任务而言,这些变化不会给用户带来明显的差异。这更多是出于“积少成多”的理念,即任何功能都不应运行得比必要速度更慢。以下是 curl 8.23.0 版本中包含的一些改进,该版本将于明天(10 月 14 日)发布。
faster base64 encoding and decoding With a few different changes, the internal base64 encoding function is more than twice as fast, while base64 decoding is 40% faster.
更快的 base64 编码和解码:通过几项不同的更改,内部 base64 编码函数的运行速度提升了两倍以上,而 base64 解码速度则提升了 40%。
faster URL encoding and decoding Meaning percent encoding the octets that are not safe to use in URLs. The decoding function now runs more than twice as fast compare to before, while the encoding function is around four times as fast.
更快的 URL 编码和解码:指对 URL 中不安全的八位字节进行百分号编码。解码函数的运行速度现在比以前快了两倍多,而编码函数的运行速度则快了约四倍。
faster date parsing Converting a date provided in plain ASCII text, as is used in for example cookie headers, to the epoch – number of seconds since Jan 1st 1970, is now more than twice as fast as before. Mostly thanks to completely replaced functions for week day, month name and time zone name lookups.
更快的日期解析:将纯 ASCII 文本提供的日期(例如 cookie 标头中使用的日期)转换为纪元时间(自 1970 年 1 月 1 日以来的秒数),现在的速度比以前快了两倍多。这主要归功于完全替换了用于查找星期几、月份名称和时区名称的函数。
faster URL parsing Parsing a full URL to split it up into separate components as well as confirming its validity is a core component of curl, and libcurl exposes this functionality in its API. In a test with several hundred different URLs, the new version executes 20-30% faster than before – with an improved ability to return precisely what the problem was when the URL is considered invalid.
更快的 URL 解析:解析完整 URL 以将其拆分为独立组件并确认其有效性是 curl 的核心组件,libcurl 在其 API 中公开了此功能。在包含数百个不同 URL 的测试中,新版本的执行速度比以前快了 20-30%,并且在 URL 被视为无效时,能够更精确地返回问题所在。
faster printf() calls For portability and now historical reasons, libcurl has its own printf() implementation. This ensures that it always works identically on all platforms but it also makes it our job to make sure it executes as fast as possible. Most printf() calls now run slightly faster (5-15%) because it handles “chunks” instead of single byte-by-byte at a time.
更快的 printf() 调用:出于可移植性和历史原因,libcurl 拥有自己的 printf() 实现。这确保了它在所有平台上都能以相同方式工作,但也要求我们必须确保其执行速度尽可能快。大多数 printf() 调用现在的运行速度略有提升(5-15%),因为它现在处理的是“数据块”而非一次一个字节。
faster number parsing We have a generic internal function in curl that converts a number provided in ascii to its binary version (for decimal, hexadecimal and octal). It handles 64 bit values, has overflow detection and supports a maximum. This parser now runs almost twice as fast as before thanks to a simple trick to avoid the boundary check for most loops.
更快的数字解析:curl 中有一个通用的内部函数,用于将 ASCII 提供的数字转换为二进制版本(适用于十进制、十六进制和八进制)。它处理 64 位值,具有溢出检测功能并支持最大值。得益于一个避免大多数循环边界检查的简单技巧,该解析器的运行速度现在几乎比以前快了两倍。
smaller structs The easy handle was 4256 bytes large two months ago, it is now 3064 bytes. About 28% trimmed off. One of these structs is allocated for every concurrent transfer done with libcurl. There is also one multi handle allocated for each set of transfer. This struct shrunk from 900 bytes to 656: 27%. The connectdata struct that is allocated once per connection libcurl handles, went down from 824 to 656 bytes: slightly over 20%.
更小的结构体:easy handle 在两个月前的大小为 4256 字节,现在为 3064 字节,缩减了约 28%。使用 libcurl 进行的每次并发传输都会分配一个这样的结构体。此外,每组传输还会分配一个 multi handle,该结构体从 900 字节缩小到 656 字节,缩减了 27%。libcurl 处理的每个连接都会分配一次 connectdata 结构体,其大小从 824 字节降至 656 字节,缩减了略高于 20%。
fewer and smaller allocations For the test case where we count all allocations necessary for the curl tool to download a single 512MB file over clear text HTTP://, it went down from 100 to 96 used allocations. Not too exciting perhaps but it is now really hard to squeeze this further! Mostly thanks to the decreased struct sizes mentioned above, this use case of a single HTTP download now only use 126,875 bytes allocated at peak. Down from 130,622 bytes two months ago. Also quite difficult to trim further. It should be noted that the download buffer is 102,400 bytes of this amount. If we exclude that buffer from the count, curl is using 15% less memory.
更少且更小的内存分配:在测试用例中,我们统计了 curl 工具通过明文 HTTP:// 下载单个 512MB 文件所需的所有分配,分配次数从 100 次降至 96 次。这或许并不令人兴奋,但现在确实很难再进一步压缩了!主要得益于上述结构体大小的减小,单个 HTTP 下载的用例现在峰值仅占用 126,875 字节的内存,低于两个月前的 130,622 字节。这也同样很难再进一步精简。需要注意的是,下载缓冲区占用了其中的 102,400 字节。如果我们从统计中排除该缓冲区,curl 的内存使用量减少了 15%。
Easy to check If you think you can speed up any of these functions, it is now very easy to check: the tests are there in the git repository, ready to be invoked by anyone! Sorry, very pedantic but I don’t understand some of the percentages for the smaller structs 4256 bytes to 3064; that’s 1192 bytes saved or 28% of 4256. 900 bytes to 656 is 27% saved 824 to 656 bytes is just over 20% saved. Reply I clearly failed at math here… Thanks, the post has been corrected. Reply
易于检查:如果您认为自己可以加速其中任何函数,现在检查起来非常容易:测试代码就在 git 仓库中,随时可供任何人调用!抱歉,我比较吹毛求疵,但我不太理解关于较小结构体的一些百分比:4256 字节到 3064 字节,节省了 1192 字节,即 4256 的 28%;900 字节到 656 字节节省了 27%;824 字节到 656 字节节省了略高于 20%。回复:我显然在数学上犯了错……谢谢,文章已更正。回复