[
https://issues.apache.org/jira/browse/VELOCITY-607?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jarkko Viinamäki updated VELOCITY-607:
--------------------------------------
Attachment: velocity-1.6-macro-performance-IDEAS.patch
First things first:
1. This is not a real production quality patch. It contains some ideas and
major design changes that I tried when trying to make Velocity 1.6 new macro
implementation perform better. I have done some functional, performance and
load testing but not nearly enough.
2. Although tests pass, I have most probably broken some functionality
especially regarding error messages and namespaces.
3. I have tested these changes with several hundred concurrent threads which
does not mean that they are free from race conditions, locking issues etc.
nasty stuff.
4. Even after this patch Velocity 1.6 svn head is around 10-20% slower than
1.5. I didn't investigate 1.5 code that much but I suspect that Velocity 1.5
fully preconstructs templates by duplicating macro AST and precalculates values
for constant macro arguments. This patch however uses shared macro ASTs which
should reduce memory usage but introduces a bunch of new problems.
Main ideas of this patch:
1. When a macro is parsed and thrown into Macro.processAndRegister, it is not
transformed and stored as String but as AST.
2. VelocimacroManager does not create new VelocimacroProxy for each request but
creates one per macro / namespace. Thus threads share the macro AST.
3. VMContext and VMProxyArg have been replaced with ProxyVMContext. This allows
us to skip parsing of macro arguments when macro is invoked and it reduces
memory allocation overhead.
4. "Render literal if null for references" is tricky to implement with shared
macro AST. Velocity 1.5 implements this by preprocessing the AST tree with
visitor.VMReferenceMungeVisitor. As far as I understand, this is not possible
with shared macro AST. Therefore there's a rather ugly hack which puts macro
argument references to the macro rendering context. ASTReference can then
construct the literal format of arguments on-demand.
Other notes:
1. ExtendedProperties class is synchronized and very slow overall (it even says
so in the JavaDocs). There are quite many runtime calls to this class
throughout the Velocity code.
2. I haven't really investigated yet if this version even uses less memory than
1.5. If the memory usage isn't significantly lower, I don't see much point in
using 1.6.
3. I probably made some catastrophic design mistakes but it takes time to
understand velocity functionality and design. Please forgive me. :)
> Runtime macro rendering very slow in Velocity 1.6-dev (679708) compared to 1.5
> ------------------------------------------------------------------------------
>
> Key: VELOCITY-607
> URL: https://issues.apache.org/jira/browse/VELOCITY-607
> Project: Velocity
> Issue Type: Bug
> Components: Engine
> Environment: Maven 2, JUnit, JUnitPerf, JRat, custom testbench:
> http://www.iki.fi/wyla/velocity/testbench
> Reporter: Jarkko Viinamäki
> Priority: Critical
> Fix For: 1.6
>
> Attachments: velocity-1.5-velocity24-test.PNG,
> velocity-1.6-head-20080725-velocity24-test.PNG,
> velocity-1.6-macro-performance-IDEAS.patch
>
>
> The following test template (see VELOCITY-24):
> ## local macro, not global
> #macro(letter $char)
> This is the letter $char
> #end
> #letter("A")
> #letter("B")
> #letter("C")
> #letter("D")
> #letter("E")
> #letter("F")
> #letter("G")
> #letter("H")
> #letter("I")
> #letter("J")
> #letter("K")
> #letter("L")
> #letter("M")
> #letter("N")
> #letter("O")
> #letter("P")
> #letter("Q")
> #letter("R")
> #letter("S")
> #letter("T")
> #letter("U")
> #letter("V")
> #letter("W")
> #letter("X")
> #letter("Y")
> #letter("Z")
> ---
> Works quickly and correctly with Velocity 1.5 with several concurrent
> threads. However, 1.6-dev is a LOT slower (even 20x).
> The major performance bottlenecks seem to be:
> RuntimeMacro.render (60% of time)
> VelocimacroFactory.getVelocimacro (20% of time)
> With several threads this test also causes Velocity to throw error(s):
> org.apache.velocity.exception.MacroOverflowException: Exceed maximum 20 macro
> calls. Call Stack:letter->letter->letter->letter->letter
> at
> org.apache.velocity.runtime.VelocimacroFactory.startMacroRendering(VelocimacroFactory.java:179)
> at
> org.apache.velocity.runtime.RuntimeInstance.startMacroRendering(RuntimeInstance.java:1693)
> at
> org.apache.velocity.runtime.directive.VelocimacroProxy.render(VelocimacroProxy.java:200)
> at
> org.apache.velocity.runtime.directive.RuntimeMacro.render(RuntimeMacro.java:230)
> at
> org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:178)
> at
> org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:323)
> at org.apache.velocity.Template.merge(Template.java:324)
> at org.apache.velocity.Template.merge(Template.java:232)
> at
> org.apache.velocity.test.load.Velocity24Test.testRendering(Velocity24Test.java:51)
> This is related to VELOCITY-297 but the fix doesn't seem work with the new
> modified macro implementation.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]