WRT the line no stuff, I threw out the instance variable manipulation
because I threw everything out.  I didn't justify it by benchmarking
just that.  Now that I've been playing around without throwing
everything away first, I benchmarked with them, commented them out and
benchmarked without them.  It makes a tiny difference, but not even
remotely significant in the current grand scheme of things.  In my
fast & dirty version I did make the lines match up and it was a god
damn bitch.  Hard to debug too because I ended up making my compiled
version much less human unreadable.

The engine as it stands is currently not far from being able to pre-
render everything.  After I posted the "throw all formatting away for
speed" version (which I'm still using in production, but hopefully
won't have to soon), I started thinking about how to get the pretty
formatting version as close to pre-rendered as possible while working
with the restriction of not throwing formatting tricks away just
because they are unfriendly to optimization (like user adjustable
tabulation).

Pre-rendering the tags is the first step.  In doing that, it gets rid
of a lot of the @one_liner_pending situations that make it difficult
to tell if you can merge text.  By also pre-rendering end tags, which
is trivial, all the text in the engine is now pre-rendered.  Well,
discounting flattened stuff, which I don't deal with because I don't
understand all the rules for handling it nicely.  I don't use a lot of
flattened stuff though, and really the vast majority of lines in real
life files will not be flattened, so optimization-wise it's not worth
worrying about much.  So that just leaves our nemesis: custom-
tabulation.

With all these perf patches applied, and then swap the various
tabulating push text calls with call that just shove text right into
_erbout, you pretty much immediately jump to parity with erb.  The
only thing preventing just baking the tabs into the strings and
spitting them out is custom tabulation.  And I've been wracking my
brains trying to figure out how to get around it.  My main idea is to
bake in the regular tabs, and then use the gsub method of inserting
more tabs per line only if custom tabulation has actually been set.
If its zero, just spit the string out.  The problem is that a lot of
the overhead is just doing the damn method calls in the first place,
even just to check if custom tabulation is in action.  Spitting lots
of _erbout << "Pre-rendered line" into my fast & dirty compiled method
was why it ended up so much faster than erb.  I need to think of a
cheap inline way of figuring out if custom tabulation has been
activated to jump to the slow gsub'ing method.

While I'm at it, I'll mention the one other perf bottleneck I'm aware
of: inserting tabulation into everything that comes back from script.
To get the tabulation of partials right (mostly for that), all the
results of script calls have tabulation gsub'ed in at the beginning of
every line.  You'll notice if you turn this off and benchmark that a
fair amount of time is spent doing just this.  This is the sort of
things that I really feel should be controlled by engine options.
It's easy to turn off and immediately see a boost, but there is no way
of speeding it up and still retain the default Haml "pretty"
behaviour.  In a related note, I made some benchmarks that make use of
lots of partial nesting.  They obviously suffer from this and the haml/
erb ratio becomes worse than shown in the standard benchmark.

That's it.  You've mentioned wanting to achieve performance parity
with erb with a rewrite/Haml 2.0, I think you are underestimating how
close the engine already is to such a thing, and should be achievable
in the very short term.  As far as I can tell, and you can see I've
been monkeying with the guts quite a bit, there's nothing refactoring
won't fix better than any kind of aggressive rewrite.  I have a couple
more patches to clean up and post which hopefully bring it to erb
parity (if I am not defeated by handling custom tabs), so hopefully
I'll shortly prove my point with working code :)

-Tom

On Jun 2, 6:53 pm, Nathan Weizenbaum <[EMAIL PROTECTED]> wrote:
> Tom Bagby wrote:
> > Sorry, about overlooking things in the string literal parsing.
>
> No worries.
> > prerender_static_tags.diff is probably the last in my series of
> > optimizations in this vein, heh.  open_tag is by far the most
> > expensive buffer operation.  This patch takes tags which have no
> > dynamic content, and prerenders them as text.
>
> > Before: Haml/ERB: 1.97723
> > After: Haml/ERB: 1.7577
>
> Sounds very good. Eventually this sort of thing will be unnecessary, as
> we'll be pre-rendering everything possible, but for now it's excellent.
>
> > To things you should probably note/decide about in the diff.  I made
> > one_liner? a class method on Buffer so I could call it from Engine.  I
> > cut & pasted build_attributes from Buffer to Engine to use in the
> > prerender.  It has instance variables that make it unfriendly to being
> > a class method, I leave it to you how best to share this functionality
> > without repeating.
>
> Duly noted.
> > I have two unrelated questions/suggestions:
>
> > 1) In the TODO, it mentions wanting to:
>
> >> Get rid of line number counting and make template lines one-to-one with 
> >> precompiled lines
>
> > I've benchmarked related to this, and it doesn't impact performance
> > much.  Is that the only reason to get rid of this?  My other
> > suggestion is that making a line for line matchup is tedious and error
> > prone.  You've mentioned other reasons for keeping around the
> > precompiled templates.  If those were always there, you could stub out
> > the @haml_lineno lines as comments, [EMAIL PROTECTED], you could then use
> > the same search strategy as for finding line no's of compile errors
> > with no impact on the runtime.
>
> Interesting point. Yes, that was mostly for performance reasons (I
> thought you had done something before that suggested it was useful), so
> commenting is probably a better solution.> 2) What's the intended use of 
> @tabulation in Buffer?  It seems like
> > helpers can set it to do custom tabbing?  A lot of time is spent
> > tabulating what could just be static pre-indented strings.  Treating
> > extra tabulation as a special case is very fruitful for speeding
> > things up, so I just want to make sure my assumptions about why it's
> > used/useful are right.
>
> Yes, the buffer @tabulation keeps track of extra tabs that can be set
> via helpers. This is used for stuff like modifying form_tag so it
> produces nice output, and could be treated as a special case.
>
> - Nathan


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Haml" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/haml?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to