Description
Benchmarks show that simple queries are slower in Oak than in Jackrabbit 2.x. The profiling data shows that most time is spent in the MemoryNodeBuilder (see below), called from MutableTree, even thought the query engine internally doesn't need mutable trees.
It would be nice if creating a tree is faster (MemoryNodeBuilder, MutableTree and related). Many components would benefit from that. Unfortunately, the code is quite complex (meaning, I don't understand it).
I found two alternatives to speed up queries:
- Not use MutableTree within the query engine, but instead use ImmutableTree. This gave a small performance boost (maybe 15%)
- Cache trees in the query engine, to avoid creating the same tree multiple times. This gave a speedup of about 50% (twice as fast) for some tests.
Package summary and top stack trace as reported by the profiler.
summary: 65%: org.apache.jackrabbit.oak.plugins.memory 9%: org.apache.jackrabbit.oak.plugins.segment 4%: org.apache.jackrabbit.oak.jcr.session.operation 3%: org.apache.jackrabbit.oak.query 2%: com.google.common.collect 2%: org.apache.jackrabbit.oak.namepath 341/3234 (10%): org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder$ConnectedHead.getCurrentNodeState(MemoryNodeBuilder.java:601) org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder$UnconnectedHead.update(MemoryNodeBuilder.java:535) org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder.head(MemoryNodeBuilder.java:152) org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder.exists(MemoryNodeBuilder.java:254) org.apache.jackrabbit.oak.core.SecureNodeBuilder.getChildNode(SecureNodeBuilder.java:299) org.apache.jackrabbit.oak.core.MutableTree.<init>(MutableTree.java:76) org.apache.jackrabbit.oak.core.MutableTree.createChild(MutableTree.java:86) org.apache.jackrabbit.oak.core.MutableTree.getChild(MutableTree.java:222) org.apache.jackrabbit.oak.util.TreeUtil.getTree(TreeUtil.java:169) org.apache.jackrabbit.oak.query.QueryImpl.getTree(QueryImpl.java:604) org.apache.jackrabbit.oak.query.ast.AstElement.getTree(AstElement.java:126) org.apache.jackrabbit.oak.query.ast.SelectorImpl.currentTree(SelectorImpl.java:351)
Some benchmark results for the oak-run SimpleSearchTest with combination of changes (patch will follow). Just "N", meaning number of iterations within 10 seconds (higher is better), using Oak-Tar:
- old (mutable tree, no cache): 36
- immutable tree only: 42
- cache only: 65
- cache+immutable: 76