Great work Andreas. I'm eager to see this applied.
Thanks
-Vincent
On Jun 9, 2010, at 10:38 PM, Andreas Jonsson wrote:
> Hi,
>
> I did a quick benchmarking on the right service, to see what the
> benefits of caching is. I measured the time in nano-seconds over the
> methods checkAccess and hasAccessLevel. The server is run on a
> virtual machine, so the statistics is not entirely reliable.
> I have made some interesting observations, however:
>
> * hasAccessLevel is called a large number of times per page view. It
> is called around 20 times as often as checkAccess, which should
> normally be called once per accessed wiki-document.
>
> * The main reason for the large number of calls to hasAccessLevel are
> these variable initializations in xwikivars.vm:
>
> #set($hasEdit = $xwiki.hasAccessLevel("edit"))
> #set($hasAdmin = $xwiki.hasAccessLevel("admin"))
> ## Note: In order to know if the user has the right to create a space we
> compute a space name that doesn't exist and check edit rights on that space
> #set($hasCreateSpace = $xwiki.hasAccessLevel("edit",
> "${doc.space}${mathtool.random(0,
> 999)}.DocumentReservedForInternalXWikiUsage"))
> ## Note: In order to know if the user has the right to create a page we
> compute a page name that doesn't exist and check edit rights on that page
> #set($hasCreatePage = $xwiki.hasAccessLevel("edit",
> "${doc.space}.DocumentReservedForInternalXWikiUsage${mathtool.random(0,
> 999)}"))
> #set($hasGlobalAdmin = $xwiki.hasAccessLevel("admin", $context.user,
> "XWiki.XWikiPreferences"))
> ## Note: The document name is not internally used to determine if a user
> has programming access level. We pass XWiki.XWikiPreferences for
> consistency with the call for global admin
> #set($hasProgramming = $xwiki.hasAccessLevel("programming",
> $context.user, "XWiki.XWikiPreferences"))
> #set($hasSpaceAdmin = $xwiki.hasAccessLevel("admin", $context.user,
> "${doc.space}.WebPreferences"))
>
> Due to the ugly hack with randomly generated space names and document
> names for initiating the variables "$hasCreateSpace" and
> "$hasCreatePage", the caching implementation perform worse than it
> could, as this will cause many cache misses and waste cache space.
> However, my new implementation internally operates by computing and
> caching the rights corresponding to an EntityReference, which may
> refer to a document, a space, or a wiki. If this is exposed via the
> API it will be possible to query for the rights on a space and wiki
> directly.
>
> By removing the randomness :
>
> #set($hasCreateSpace = $xwiki.hasAccessLevel("edit",
> "${doc.space}INTERNAL.DocumentReservedForInternalXWikiUsage"))
> #set($hasCreatePage = $xwiki.hasAccessLevel("edit",
> "${doc.space}.DocumentReservedForInternalXWikiUsage"))
>
> and running a test by reloading the same page over and over, we see
> the benefit of caching:
>
> Original implementation:
>
> Statistics for checkAccess:
>
> DescriptiveStatistics:
> n: 2030
> min: 522859.0
> max: 5.39733259E8
> mean: 1.7198616874876842E7
> std dev: 3.7962038152575314E7
> median: 659100.0
> skewness: 4.262358507299374
> kurtosis: 30.885271611362477
>
> Statistics for hasAccessLevel:
>
> DescriptiveStatistics:
> n: 39402
> min: 69016.0
> max: 6.40750283E8
> mean: 8595126.655296639
> std dev: 2.770284412153291E7
> median: 592985.0
> skewness: 5.682505086745415
> kurtosis: 50.72341779375682
>
> -----------------------------------------
>
> My new implementation:
>
> Statistics for checkAccess:
>
> DescriptiveStatistics:
> n: 2030
> min: 27763.0
> max: 3.01349107E8
> mean: 3118090.7699507335
> std dev: 1.6890870361759447E7
> median: 132935.0
> skewness: 8.995243673145804
> kurtosis: 105.30119067606974
>
> Statistics for hasAccessLevel:
>
> DescriptiveStatistics:
> n: 33368
> min: 26086.0
> max: 1.239094745E9
> mean: 767290.0766902551
> std dev: 1.0969784229187453E7
> median: 32915.5
> skewness: 55.482434651126056
> kurtosis: 5256.531317809735
>
> Considering the skewed nature of the distribution, the mean value
> cannot be used to predict the delay caused by the right service.
> Considering that hasAccessLevel seems to be called more than 30 times
> per page request, a naive interpretation suggests that over 200 ms was
> polished of the average request time (7.8 ms * 30). This is obviously
> bogus, since the mean request time was 170.027 ms for the original
> implementation and 144.743 ms for my new implementation.
>
> The requests were performed with 'ab -c 10 -n 1000 -k ':
>
> Output for original implementation:
>
> Server Software: Apache-Coyote/1.1
> Server Hostname: wiki
> Server Port: 8080
>
> Document Path: /xw/bin/view/Gob/WebHome
> Document Length: 0 bytes
>
> Concurrency Level: 10
> Time taken for tests: 170.027 seconds
> Complete requests: 1000
> Failed requests: 0
> Write errors: 0
> Non-2xx responses: 1000
> Keep-Alive requests: 995
> Total transferred: 414975 bytes
> HTML transferred: 0 bytes
> Requests per second: 5.88 [#/sec] (mean)
> Time per request: 1700.269 [ms] (mean)
> Time per request: 170.027 [ms] (mean, across all concurrent requests)
> Transfer rate: 2.38 [Kbytes/sec] received
>
> Connection Times (ms)
> min mean[+/-sd] median max
> Connect: 0 0 0.2 0 3
> Processing: 445 1694 412.3 1654 3663
> Waiting: 445 1694 412.3 1654 3663
> Total: 445 1694 412.4 1654 3663
>
> --------------------------------------------------------------------------------
>
> Output for my new implementation:
>
> Server Software: Apache-Coyote/1.1
> Server Hostname: wiki
> Server Port: 8080
>
> Document Path: /xw/bin/view/Gob/WebHome
> Document Length: 0 bytes
>
> Concurrency Level: 10
> Time taken for tests: 144.743 seconds
> Complete requests: 1000
> Failed requests: 0
> Write errors: 0
> Non-2xx responses: 1000
> Keep-Alive requests: 993
> Total transferred: 414965 bytes
> HTML transferred: 0 bytes
> Requests per second: 6.91 [#/sec] (mean)
> Time per request: 1447.426 [ms] (mean)
> Time per request: 144.743 [ms] (mean, across all concurrent requests)
> Transfer rate: 2.80 [Kbytes/sec] received
>
> Connection Times (ms)
> min mean[+/-sd] median max
> Connect: 0 0 0.2 0 4
> Processing: 374 1441 428.1 1415 3228
> Waiting: 374 1441 428.1 1415 3228
> Total: 374 1441 428.1 1415 3228
>
>
> My implementation needs some more testing, but I will try to upload it
> to Jira by tomorrow.
>
> Best regards,
>
> Andreas Jonsson
_______________________________________________
devs mailing list
[email protected]
http://lists.xwiki.org/mailman/listinfo/devs