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 -~----------~----~----~----~------~----~------~--~---
