webgrind_使用Webgrind进行快速优化

webgrind_使用Webgrind进行快速优化

webgrind

I was recently working on a site whose code I was inheriting and the pages took much longer to process than I would’ve liked. Caching helped, but I wanted to get to the underlying issue so I fired up Webgrind to see if I could trace the problem.

我最近正在一个我正在继承其代码的网站上工作,处理页面所需的时间比我想要的要长得多。 缓存有所帮助,但是我想解决潜在的问题,因此我启动了Webgrind,以查看是否可以找到问题所在。

Webgrind is a freely available PHP profiling frontend that sits on top of XDebug. Using it, you can see how many times different functions are called and find what functions called them. You can also quickly see the inclusive cost (time spent inside a function plus calls to other functions) and self cost of each function.

Webgrind是一个免费PHP分析前端,它位于XDebug的顶部。 使用它,您可以查看多少次调用了不同的函数,并找到了调用它们的函数。 您还可以快速查看包含费用(在一个函数中花费的时间以及对其他函数的调用)和每个函数的自身成本。

Viewing the logs for the last page load, I could see that mysql_query was called a whopping 52 times and accounted for 84.93% of the processing time (which was at an unacceptable ~3.1ms).

查看最后一页加载的日志,我可以看到mysql_query被调用了52次,占处理时间的84.93%(这是不可接受的〜3.1ms)。

Using the Webgrind frontend, I was able to trace back 23 of those calls to one function. In turn, this function was called by one other function 17 times. I decided to focus there first.

使用Webgrind前端,我能够将其中的23个调用追溯到一个函数。 依次,该函数被另一个函数调用了17次。 我决定首先集中精力。

Again, with the help of Webgrind, I could see that this function was called several times, in  separate files, for each page. The function produced the same results each time it was called.

再次,在Webgrind的帮助下,我可以看到针对每个页面在单独的文件中多次调用了此函数。 每次调用该函数都会产生相同的结果。

The quick and simple fix, then, was to use a property to cache the results of that function call. So the first time it was called, it would process completely and run the necessary queries. The next time it was called, it would check it’s cache property to see if a value existed for the parameter being passed. If the value did exist - it would return that value.

然后,快速而简单的解决方法是使用属性来缓存该函数调用的结果。 因此,第一次调用它时,它将完全处理并运行必要的查询。 下次调用它时,它将检查它的cache属性,以查看所传递的参数是否存在值。 如果该值确实存在,它将返回该值。

This simple optimization immediately brought the total queries down from 52 to 36. They still accounted for 74% of the processing time, but that time had dropped dramatically from 3.1ms to ~2ms.

这种简单的优化立即使总查询从52个减少到36个。它们仍然占处理时间的74%,但是该时间从3.1ms急剧下降到了2ms。

36 queries was still more than I wanted. A similar function to the one I had just optimized was responsible (both indirectly and directly) for 25 of the remaining 36 queries, so I thought I’d take a look there next.

36个查询仍然超出我的需求。 与我刚刚优化过的函数类似的功能(间接和直接)负责其余36个查询中的25个,因此我想接下来看看。

Looking at the source, I could see that while the function asked for a boolean parameter to indicate if it should run certain queries, it never actually checked the value of that parameter. So no matter what, it was running all the queries, all the time. Fixing that error brought the total query count down from 36 to 16 and the total time to process the page was now ~1ms.

从源头上看,我看到虽然该函数要求一个布尔参数来指示它是否应该运行某些查询,但它从未实际检查该参数的值。 因此,无论如何,它一直在运行所有查询。 解决该错误使查询总数从36减少到16,现在处理该页面的总时间约为1ms。

As a surprising bonus, there were no locations in the code that I had to change now that the function had been corrected. People hadn’t been expecting to get those extra values in their return object, so they never tried to use them unless they had passed a true value in for that parameter.

令人惊讶的是,由于该函数已被更正,因此我无需更改代码中的任何位置。 人们并没有期望在返回对象中获得这些额外的值,因此除非他们为该参数传递了真值,否则他们从不尝试使用它们。

All in all I was able to take the query count down from 52 to 16 and the processing time from ~3.1ms to ~1ms. There’s more room for optimization, but this is certainly not a bad start for about 45 minutes of work.

总之,我能够将查询计数从52减少到16,并将处理时间从〜3.1ms减少到〜1ms。 还有更多的优化空间,但是对于大约45分钟的工作来说,这当然不是一个不好的开始。

翻译自: https://timkadlec.com/2010/08/quick-optimization-using-webgrind/

webgrind