bobthecow / mustache.php

A Mustache implementation in PHP.
http://mustache.github.io/
MIT License
3.24k stars 420 forks source link

[RESEARCH] Compiled files are too large #150

Closed sergeevabc closed 11 years ago

sergeevabc commented 11 years ago

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.

Template includes another template, two variables.

1. Compile and execute (alphabetical order).

Haanga 1.0.4                in 11400 . out 12289
- start: 333 912 bytes
- end:   2 625 184 bytes
- peak:  2 704 904 bytes
- time:  0.0362 seconds

Mustache                    in 11388 . out 19494
- start: 335 352 bytes
- end:   1 013 608 bytes
- peak:  1 126 248 bytes
- time:  0.1215 seconds

RainTPL 3                   in 11388 . out 11727
- start: 336 352 bytes
- end:   701 240 bytes
- peak:  836 504 bytes
- time:  0.0265 seconds

Smarty 3.1                  in 11399 . out 13453
- start: 335 192 bytes
- end:   4 119 448 bytes
- peak:  4 241 736 bytes
- time:  0.0593 seconds

Twig 1.13.0                 in 11398 . out 13184
- start: 335 408 bytes
- end:   3 240 480 bytes
- peak:  3 315 304 bytes
- time:  0.0809 seconds

2. Execute compiled template from cache.

Haanga
- start: 334 280 bytes
- end:   469 200 bytes
- peak:  546 672 bytes
- time:  0.0060 seconds

Mustache
- start: 335 720 bytes
- end:   711 424 bytes
- peak:  783 464 bytes
- time:  0.0134 seconds

RainTPL
- start: 336 720 bytes
- end:   690 880 bytes
- peak:  761 560 bytes
- time:  0.0109 seconds

Smarty
- start: 335 560 bytes
- end:   1 609 056 bytes
- peak:  1 702 416 bytes
- time:  0.0191 seconds

Twig
- start: 335 776 bytes
- end:   1 305 280 bytes
- peak:  1 363 856 bytes
- time:  0.0177 seconds

Memory consumption is relatively good, so hooray for Mustache? Not yet, check the output size! 19.5 Kbytes? WTF?

bobthecow commented 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?

sergeevabc commented 11 years ago

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.

bobthecow commented 11 years ago

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.

sergeevabc commented 11 years ago

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?

sergeevabc commented 11 years ago

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
bobthecow commented 11 years ago

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 :)

sergeevabc commented 11 years ago

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