On 09/01/2011 10:41 AM, Caleb James DeLisle wrote:
I ran some testing by injecting printline statements
after the beginning of each synchronization block
in all of the xwiki codebase and then ran some tests.
xwiki webstandards test:
pages loaded: 925
synchronization blocks entered: 2,512,524
synchronizations per page: 2,716
Excluding the first page load on start-up, these are the total synchronizations from
running the
webstandards tests. Note that they don't add up to exactly 2,512,524 because some
were spoiled when
2 threads tried to write to stdout simultaneously.
Total Percent Location
1651401 65.73% XWikiCacheStore.java:115
316411 12.59% EmbeddableComponentManager.java:352
142094 5.66% XWikiContext.java:260
103028 4.10% XWiki.java:5380
58151 2.31% XWikiContext.java:282
54891 2.18% XWiki.java:5455
46324 1.84% DefaultVelocityFactory.java:72
46320 1.84% DefaultVelocityFactory.java:82
29447 1.17% EmbeddableComponentManager.java:138
15010 0.60% DefaultBeanManager.java:204
14595 0.58% DefaultXWikiRenderingEngine.java:239
10933 0.44% URIClassLoader.java:438
3812 0.15% XWiki.java:5406
3262 0.13% DefaultVelocityEngine.java:227
3262 0.13% DefaultVelocityEngine.java:245
2867 0.11% XWikiNotificationManager.java:130
1941 0.08% XWikiGroupServiceImpl.java:798
958 0.04% XWikiConfigurationService.java:50
958 0.04% XWikiNotificationManager.java:254
958 0.04% XWikiNotificationManager.java:265
957 0.04% XWikiCacheStore.java:704
951 0.04% XWikiNotificationManager.java:230
949 0.04% XWikiNotificationManager.java:241
917 0.04% XWikiNotificationManager.java:219
852 0.03% XWikiStatsServiceImpl.java:182
371 0.01% XWikiDocumentQueue.java:88
351 0.01% XWikiDocumentQueue.java:55
142 0.01% XWikiDocumentQueue.java:69
112 0.00% XWikiDocumentQueue.java:98
66 0.00% AdminAction.java:57
24 0.00% RightsManager.java:164
15 0.00% EditAction.java:59
UI tests were also run to give a more well rounded view of what real traffic might look
like:
1666727 57.98% XWikiCacheStore.java:115
463369 16.12% EmbeddableComponentManager.java:352
234027 8.14% XWiki.java:5380
175972 6.12% XWikiContext.java:260
70156 2.44% XWikiContext.java:282
65952 2.29% XWiki.java:5455
43553 1.52% DefaultVelocityFactory.java:72
43552 1.52% DefaultVelocityFactory.java:82
33512 1.17% EmbeddableComponentManager.java:138
13451 0.47% DefaultBeanManager.java:204
9650 0.34% DefaultXWikiRenderingEngine.java:239
9450 0.33% XWikiNotificationManager.java:130
5176 0.18% XWikiGroupServiceImpl.java:798
5019 0.17% URIClassLoader.java:438
3965 0.14% XWiki.java:5406
2850 0.10% DefaultVelocityEngine.java:227
2850 0.10% DefaultVelocityEngine.java:245
2717 0.09% XWikiConfigurationService.java:50
2694 0.09% XWikiCacheStore.java:704
2624 0.09% XWikiNotificationManager.java:219
2624 0.09% XWikiNotificationManager.java:230
2624 0.09% XWikiNotificationManager.java:241
2590 0.09% XWikiNotificationManager.java:254
2590 0.09% XWikiNotificationManager.java:265
749 0.03% XWikiDocumentQueue.java:69
718 0.02% XWikiStatsServiceImpl.java:182
554 0.02% XWikiDocumentQueue.java:88
550 0.02% EmbeddableComponentManager.java:201
476 0.02% XWikiDocumentQueue.java:55
406 0.01% XWikiHibernateVersioningStore.java:142
403 0.01% XWikiNotificationManager.java:140
403 0.01% XWikiNotificationManager.java:155
403 0.01% XWikiNotificationManager.java:167
403 0.01% XWikiNotificationManager.java:181
403 0.01% XWikiNotificationManager.java:194
403 0.01% XWikiNotificationManager.java:206
282 0.01% XWikiDocumentQueue.java:98
209 0.01% EditAction.java:59
101 0.00% RightsManager.java:164
81 0.00% AdminAction.java:57
61 0.00% EmbeddableComponentManager.java:289
52 0.00% EmbeddableComponentManager.java:256
44 0.00% LucenePlugin.java:656
35 0.00% InlineAction.java:39
23 0.00% DefaultCSRFToken.java:130
19 0.00% MutableHttpServletRequestFactory.java:43
15 0.00% AbstractGenericComponentManager.java:93
13 0.00% LucenePlugin.java:450
5 0.00% XWikiNotificationManager.java:56
2 0.00% MacroRepository.java:65
2 0.00% XWiki.java:408
1 0.00% ActivityStreamCleaner.java:89
1 0.00% EmbeddableComponentManager.java:163
1 0.00% EmbeddableComponentManager.java:269
1 0.00% RightsManagerListener.java:85
1 0.00% SchedulerPlugin.java:561
1 0.00% StackingComponentEventManager.java:69
1 0.00% XWikiGroupServiceImpl.java:150
1 0.00% XWikiGroupServiceImpl.java:162
1 0.00% XWikiGroupServiceImpl.java:180
1 0.00% XWikiHibernateBaseStore.java:142
1 0.00% XWikiHibernateBaseStore.java:265
1 0.00% XWikiHibernateBaseStore.java:557
1 0.00% XWiki.java:5493
1 0.00% XWiki.java:5515
These numbers seem to be quite conclusive that XWikiCacheStore.java:115 is the lowest
hanging fruit
in the synchronization field. An examination of XWikiCacheStore reveals that the
"per load"
synchronization should be avoidable if it is not lazy initialized and is flushed
differently.
Lazy initialization is bad. Historically, it has been done this way in
many places since the context is not available too early. This
XWikiContext class is a very bad item causing a lot of problems in the
old core.
Is synchronization the best place to attack for
performance gains?
Synchronization cost is difficult to measure because it varies based on number of
processor cores and
processor sockets. In the worst case, the caches in multiple cores on multiple processor
sockets all
need to be flushed and this would be the case with high contention mutexes.
As a matter of good practice, I think we should reduce the amount of synchronization as
much as is reasonable.
Yes, it is a valid goal to reduce as much as possible the list of
synchronized methods and blocks, and attempts in this direction have
been previously made.
IMO bad synchronization is a very good candidate for performance
improvements, since that many synchronizations for one request makes it
very likely that most of the time only one request gets to be executed,
making XWiki behave worse than a single-threaded application.
--
Sergiu Dumitriu
http://purl.org/net/sergiu/