Closed sergeevabc closed 11 years ago
I haven't done a comparison like this, but intuitively it seems to me that disk space is relatively cheap, but RAM and time are scarce resources. So templating languages should optimize for RAM usage and warm-cache execution time, right?
It's very frustrating to get such a reply from senior developer. Double facepalm as they say. It's like someone still states Sun goes around the Earth or continents are fixed, you know, almost a dead-end, or bloatware-end in our case.
Jeff Atwood at CodingHorror wrote back in 2005: "Computers get faster every day, but our brains don't". What does it mean? It means some of us are too lazy to discover, compare, learn and adapt best practices, they prefer to exploit finite resources for short-term pleasures ("wow, I made it work!"), but not own will for long-term sweeping changes.
I believe you're better than this, so start optimizing ugly $buffer output today. Tip: have a look how Haanga and RainTPL3 achieve better output with smaller footprint.
The funny thing about "better" is that it's entirely subjective. I'd say the mustache output is "better" because it doesn't use output buffering, while both of those implementations do. I'd say the mustache output is "better" because with it you get a template object which can be treated like an object. You don't get a file to include (and output buffer). You don't get a globally namespaced crazy function. You get an object.
Note that those two things, like many things in software development, are completely subjective. The compiled template sources look the way they do because, like many things in software development, they are an intersection of many different optimizations.
Can the mustache output be better? Absolutely. Do I want it to be better? Absolutely. Here are a couple of the ways I see that the output could be cleaner while still maintaining the two advantages listed above.
Is it worth optimizing the compiled templates for file size too? In my opinion, no.
You see, the other funny thing is, that's not what Jeff Atwood was arguing for at all. He was, in fact, arguing that it's perfectly reasonable for software to get more bloated, use more memory, and be coded at a higher level as time goes on.
The subset of tasks that must be done in (insert favorite low-level language here) for acceptable performance gets smaller and smaller every day as hardware improves over time. This is a perfectly reasonable tradeoff to make; computers get faster every day, but our brains don't. The goal of the .NET runtime is not to squeeze every drop of performance out of the platform-- it's to make software development easier.
In other words, he agrees with me.
Jeff Atwood points out the true nature of NET runtime: easier for juveniles who lack the ability to write sophisticated code. Start with it, rely on faster hardware to conceal your weaknesses, but eventually get smarter, because even a couple of changes could cut overall consumption in half. Haven't you noticed mature people hate that apps in general?
I don't know how long you've been playing this game, but I replaced 80386 40 MHz 2 MB with Pentium 133 MHz 64 MB back in 90s to speed things up, not to encourage lazy amateurs who produce junk code. It was true for a while: e.g. enormous piles of CD and VHS turned into compact, organized and accessible mp3/flac/avi/mkv. But nowadays some notepads utilize amount of space as it were Civilization and load for seconds as it were Photoshop or Cubase. Should I upgrade again & again, that is to say, to exploit nature more extensively, and pay "relatively cheap" running costs that actually go beyond imagination of the most workers on our planet just to accomplish the same tasks in a modern way? Nah.
Current implementation of Mustache gives at least x1.7 size overhead (far more with options). It doubles required resources to store, to compress and decompress, and to transfer, so there is a room for improvement. Even a superficial glance is sufficient to rebel against treating every single line of output with $buffer and $indent. That's why I'm looking forward to test optimized Mustache build. When would it be possible?
New benchmark: one large template, two variables. (download)
1. Compile and execute (alphabetical order).
Haanga 1.0.4 in 417026 . out 417461
- start: 334 208 bytes
- end: 3 025 552 bytes
- peak: 5 105 960 bytes
- time: 0.0500 seconds
Mustache in 417026 . out 1102840
- start: 335 272 bytes
- end: 17 092 568 bytes
- peak: 21 469 744 bytes
- time: 4.4646 seconds
RainTPL 3 in 417024 . out 417190
- start: 336 280 bytes
- end: 1 107 624 bytes
- peak: 4 081 472 bytes
- time: 0.4083 seconds
Smarty 3.1 in 417024 . out 418049
- start: 335 120 bytes
- end: 4 445 992 bytes
- peak: 5 703 688 bytes
- time: 0.1088 seconds
Twig 1.13.0 in 417026 . out 406092
- start: 335 328 bytes
- end: 4 774 336 bytes
- peak: 5 869 816 bytes
- time: 0.0888 seconds
2. Execute compiled template from cache.
Haanga
- start: 334 208 bytes
- end: 869 608 bytes
- peak: 1 697 240 bytes
- time: 0.0076 seconds
Mustache
- start: 335 640 bytes
- end: 7 540 368 bytes
- peak: 9 078 888 bytes
- time: 0.0577 seconds
RainTPL
- start: 336 648 bytes
- end: 690 320 bytes
- peak: 1 568 832 bytes
- time: 0.0114 seconds
Smarty
- start: 335 488 bytes
- end: 2 002 800 bytes
- peak: 2 840 160 bytes
- time: 0.0189 seconds
Twig
- start: 335 696 bytes
- end: 1 684 336 bytes
- peak: 2 499 464 bytes
- time: 0.0194 seconds
You'll be happy to note that the feature/whitespace-tokenizing
feature branch contains a couple of optimizations for very large templates, which result in up to 50% reduction in memory use. And up to 50% reduction in $buffer .= ...
lines :)
We can call it an improvement, yes. However Mustache brings up the rear still.
MASTER
in 417 026 . out 1 102 840
bare
- start: 335 520 bytes
- end: 17 092 880 bytes
- peak: 21 470 008 bytes
- time: 4.5439 seconds
cache
- start: 335 520 bytes
- end: 7 540 256 bytes
- peak: 9 078 776 bytes
- time: 0.0579 seconds
FEATURE/whitespace-tokenizing
in 417 026 . out 814 294
bare
- start: 335 520 bytes
- end: 11 116 064 bytes
- peak: 13 876 600 bytes
- time: 4.6741 seconds
cache
- start: 335 520 bytes
- end: 5 063 016 bytes
- peak: 7 793 920 bytes
- time: 0.0452 seconds
Dear Mustache community, I'm not satisfied with wordpress-like CMS, but not ready for MVC frameworks, so PHP template engines are the very golden mean for me to maintain bilingual personal projects with a dozen partly inherited pages. Today I have done a couple of naive benchmarks: template includes another template, array turns into bulleted list and variables turn into text.
Memory consumption is relatively good, so hooray for Mustache? Not yet, check the output size! 19.5 Kbytes? WTF?