CoffeeKup optimization

JavaScript performance comparison

Revision 6 of this test case created by

Preparation code

<script src="https://raw.github.com/documentcloud/underscore/master/underscore-min.js"></script>
<script>
  var template = function anonymous(data) {
      var a, b, body, em, h1, head, header, html, i, ins, li, p, s, section, style, th, title, u, ul, font, tt, hr, meta;
      a = function() {
        return __ck.tag('a', arguments);
      };
      b = function() {
        return __ck.tag('b', arguments);
      };
      body = function() {
        return __ck.tag('body', arguments);
      };
      em = function() {
        return __ck.tag('em', arguments);
      };
      h1 = function() {
        return __ck.tag('h1', arguments);
      };
      head = function() {
        return __ck.tag('head', arguments);
      };
      header = function() {
        return __ck.tag('header', arguments);
      };
      html = function() {
        return __ck.tag('html', arguments);
      };
      i = function() {
        return __ck.tag('i', arguments);
      };
      ins = function() {
        return __ck.tag('ins', arguments);
      };
      li = function() {
        return __ck.tag('li', arguments);
      };
      p = function() {
        return __ck.tag('p', arguments);
      };
      s = function() {
        return __ck.tag('s', arguments);
      };
      section = function() {
        return __ck.tag('section', arguments);
      };
      style = function() {
        return __ck.tag('style', arguments);
      };
      th = function() {
        return __ck.tag('th', arguments);
      };
      title = function() {
        return __ck.tag('title', arguments);
      };
      u = function() {
        return __ck.tag('u', arguments);
      };
      ul = function() {
        return __ck.tag('ul', arguments);
      };
      font = function() {
        return __ck.tag('font', arguments);
      };
      tt = function() {
        return __ck.tag('tt', arguments);
      };
      hr = function() {
        return __ck.tag('hr', arguments);
      };
      meta = function() {
        return __ck.tag('meta', arguments);
      };
      var __slice = Array.prototype.slice;
      var __hasProp = Object.prototype.hasOwnProperty;
      var __bind = function(fn, me) {
          return function() {
            return fn.apply(me, arguments);
          };
          };
      var __extends = function(child, parent) {
          for (var key in parent) {
            if (__hasProp.call(parent, key)) child[key] = parent[key];
          }
          function ctor() {
            this.constructor = child;
          }
          ctor.prototype = parent.prototype;
          child.prototype = new ctor;
          child.__super__ = parent.prototype;
          return child;
          };
      var __indexOf = Array.prototype.indexOf ||
      function(item) {
        for (var i = 0, l = this.length; i < l; i++) {
          if (this[i] === item) return i;
        }
        return -1;
      };
      var coffeescript, comment, doctype, h, ie, tag, text, yield, __ck, _ref, _ref2;
      if (data == null) {
        data = {};
      }
      if ((_ref = data.format) == null) {
        data.format = false;
      }
      if ((_ref2 = data.autoescape) == null) {
        data.autoescape = false;
      }
      __ck = {
        buffer: [],
        esc: function(txt) {
          if (data.autoescape) {
            return h(txt);
          } else {
            return String(txt);
          }
        },
        tabs: 0,
        repeat: function(string, count) {
          return Array(count + 1).join(string);
        },
        indent: function() {
          if (data.format) {
            return text(this.repeat('  ', this.tabs));
          }
        },
        tag: function(name, args) {
          var combo, i, _i, _len;
          combo = [name];
          for (_i = 0, _len = args.length; _i < _len; _i++) {
            i = args[_i];
            combo.push(i);
          }
          return tag.apply(data, combo);
        },
        render_idclass: function(str) {
          var c, classes, i, id, _i, _j, _len, _len2, _ref3;
          classes = [];
          _ref3 = str.split('.');
          for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
            i = _ref3[_i];
            if (__indexOf.call(i, '#') >= 0) {
              id = i.replace('#', '');
            } else {
              if (i !== '') {
                classes.push(i);
              }
            }
          }
          if (id) {
            text(" id=\"" + id + "\"");
          }
          if (classes.length > 0) {
            text(" class=\"");
            for (_j = 0, _len2 = classes.length; _j < _len2; _j++) {
              c = classes[_j];
              if (c !== classes[0]) {
                text(' ');
              }
              text(c);
            }
            return text('"');
          }
        },
        render_attrs: function(obj, prefix) {
          var k, v, _results;
          if (prefix == null) {
            prefix = '';
          }
          _results = [];
          for (k in obj) {
            v = obj[k];
            if (typeof v === 'boolean' && v) {
              v = k;
            }
            if (typeof v === 'function') {
              v = "(" + v + ").call(this);";
            }
            _results.push(typeof v === 'object' && !(v instanceof Array) ? this.render_attrs(v, prefix + k + '-') : v ? text(" " + (prefix + k) + "=\"" + (this.esc(v)) + "\"") : void 0);
          }
          return _results;
        },
        render_contents: function(contents) {
          var result;
          switch (typeof contents) {
          case 'string':
          case 'number':
          case 'boolean':
            return text(this.esc(contents));
          case 'function':
            if (data.format) {
              text('\n');
            }
            this.tabs++;
            result = contents.call(data);
            if (typeof result === 'string') {
              this.indent();
              text(this.esc(result));
              if (data.format) {
                text('\n');
              }
            }
            this.tabs--;
            return this.indent();
          }
        },
        render_tag: function(name, idclass, attrs, contents) {
          this.indent();
          text("<" + name);
          if (idclass) {
            this.render_idclass(idclass);
          }
          if (attrs) {
            this.render_attrs(attrs);
          }
          if (__indexOf.call(this.self_closing, name) >= 0) {
            text(' />');
            if (data.format) {
              text('\n');
            }
          } else {
            text('>');
            this.render_contents(contents);
            text("</" + name + ">");
            if (data.format) {
              text('\n');
            }
          }
          return null;
        }
      };
      tag = function() {
        var a, args, attrs, contents, idclass, name, _i, _len;
        name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
        for (_i = 0, _len = args.length; _i < _len; _i++) {
          a = args[_i];
          switch (typeof a) {
          case 'function':
            contents = a;
            break;
          case 'object':
            attrs = a;
            break;
          case 'number':
          case 'boolean':
            contents = a;
            break;
          case 'string':
            if (args.length === 1) {
              contents = a;
            } else {
              if (a === args[0]) {
                idclass = a;
              } else {
                contents = a;
              }
            }
          }
        }
        return __ck.render_tag(name, idclass, attrs, contents);
      };
      yield = function(f) {
        var old_buffer, temp_buffer;
        temp_buffer = [];
        old_buffer = __ck.buffer;
        __ck.buffer = temp_buffer;
        f();
        __ck.buffer = old_buffer;
        return temp_buffer.join('');
      };
      h = function(txt) {
        return String(txt).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
      };
      doctype = function(type) {
        if (type == null) {
          type = 'default';
        }
        text(__ck.doctypes[type]);
        if (data.format) {
          return text('\n');
        }
      };
      text = function(txt) {
        __ck.buffer.push(String(txt));
        return null;
      };
      comment = function(cmt) {
        text("<!--" + cmt + "-->");
        if (data.format) {
          return text('\n');
        }
      };
      coffeescript = function(param) {
        switch (typeof param) {
        case 'function':
          return script("" + __ck.coffeescript_helpers + "(" + param + ").call(this);");
        case 'string':
          return script({
            type: 'text/coffeescript'
          }, function() {
            return param;
          });
        case 'object':
          param.type = 'text/coffeescript';
          return script(param);
        }
      };
      ie = function(condition, contents) {
        __ck.indent();
        text("<!--[if " + condition + "]>");
        __ck.render_contents(contents);
        text("<![endif]-->");
        if (data.format) {
          return text('\n');
        }
      };
      __ck.doctypes = {
        "5": "<!DOCTYPE html>",
        "default": "<!DOCTYPE html>",
        "xml": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>",
        "transitional": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">",
        "strict": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">",
        "frameset": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">",
        "1.1": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">",
        "basic": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML Basic 1.1//EN\" \"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd\">",
        "mobile": "<!DOCTYPE html PUBLIC \"-//WAPFORUM//DTD XHTML Mobile 1.2//EN\" \"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd\">",
        "ce": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"ce-html-1.0-transitional.dtd\">"
      };
      __ck.coffeescript_helpers = "var __slice = Array.prototype.slice;var __hasProp = Object.prototype.hasOwnProperty;var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };var __extends = function(child, parent) {  for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }  function ctor() { this.constructor = child; }  ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype;  return child; };var __indexOf = Array.prototype.indexOf || function(item) {  for (var i = 0, l = this.length; i < l; i++) {    if (this[i] === item) return i;  } return -1; };";
      __ck.self_closing = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr", "basefont", "frame"];
      (function() {
        doctype(5);
        html({
          lang: 'en'
        }, function() {
          head(function() {
            meta({
              charset: 'utf-8'
            });
            title(this.title);
            return style('body {font-family: "sans-serif"}\nsection, header {display: block}');
          });
          return body(function() {
            return section(function() {
              header(function() {
                return h1(this.title);
              });
              if (this.inspired) {
                p('Create a witty example');
              } else {
                p('Go meta');
              }
              return ul(function() {
                var user, _i, _len, _ref, _results;
                _ref = this.users;
                _results = [];
                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                  user = _ref[_i];
                  li(user.name);
                  _results.push(li(function() {
                    return a({
                      href: "mailto:" + user.email
                    }, function() {
                      return user.email;
                    });
                  }));
                }
                return _results;
              });
            });
          });
        });
      }).call(data);
      return __ck.buffer.join('');
      };

  var optimized = function anonymous(data) {
      __ck = {
        buffer: ''
      };
      text = function(txt) {
        if (typeof txt === 'string' || txt instanceof String) {
          __ck.buffer += txt;
        } else if (typeof txt === 'number' || txt instanceof Number) {
          __ck.buffer += String(txt);
        }
      };
      h = function(txt) {
        var escaped;
        if (typeof txt === 'string' || txt instanceof String) {
          escaped = txt.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
        } else {
          escaped = txt;
        }
        return escaped;
      };
      yield = function(f) {
        var temp_buffer = '';
        var old_buffer = __ck.buffer;
        __ck.buffer = temp_buffer;
        f();
        temp_buffer = __ck.buffer;
        __ck.buffer = old_buffer;
        return temp_buffer;
      };
      ((function() {
        text("<!DOCTYPE html>");
        text('<html lang="en">');
        text(function() {
          text("<head>");
          text(function() {
            text('<meta charset="utf-8" />');
            text("<title>");
            text(this.title);
            text("</title>");
            return function() {
              text("<style>");
              text('body {font-family: "sans-serif"}\nsection, header {display: block}');
              text("</style>");
            }.call(data);
          }.call(data));
          text("</head>");
          return function() {
            text("<body>");
            text(function() {
              return function() {
                text("<section>");
                text(function() {
                  text("<header>");
                  text(function() {
                    return function() {
                      text("<h1>");
                      text(this.title);
                      text("</h1>");
                    }.call(data);
                  }.call(data));
                  text("</header>");
                  if (this.inspired) {
                    text("<p>");
                    text("Create a witty example");
                    text("</p>");
                  } else {
                    text("<p>");
                    text("Go meta");
                    text("</p>");
                  }
                  return function() {
                    text("<ul>");
                    text(function() {
                      var user, _i, _len, _ref, _results;
                      _ref = this.users;
                      _results = [];
                      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                        user = _ref[_i];
                        text("<li>");
                        text(user.name);
                        text("</li>");
                        _results.push(function() {
                          text("<li>");
                          text(function() {
                            return function() {
                              text('<a href="');
                              text("mailto:" + user.email);
                              text('">');
                              text(function() {
                                return user.email;
                              }.call(data));
                              text("</a>");
                            }.call(data);
                          }.call(data));
                          text("</li>");
                        }.call(data));
                      }
                      return _results;
                    }.call(data));
                    text("</ul>");
                  }.call(data);
                }.call(data));
                text("</section>");
              }.call(data);
            }.call(data));
            text("</body>");
          }.call(data);
        }.call(data));
        text("</html>");
      })).call(data);
      return __ck.buffer;
      };

  var eco_template = function(__obj) {
      if (!__obj) __obj = {};
      var __out = [],
          __capture = function(callback) {
          var out = __out,
              result;
          __out = [];
          callback.call(this);
          result = __out.join('');
          __out = out;
          return __safe(result);
          },
          __sanitize = function(value) {
          if (value && value.ecoSafe) {
            return value;
          } else if (typeof value !== 'undefined' && value != null) {
            return __escape(value);
          } else {
            return '';
          }
          },
          __safe, __objSafe = __obj.safe,
          __escape = __obj.escape;
      __safe = __obj.safe = function(value) {
        if (value && value.ecoSafe) {
          return value;
        } else {
          if (!(typeof value !== 'undefined' && value != null)) value = '';
          var result = new String(value);
          result.ecoSafe = true;
          return result;
        }
      };
      if (!__escape) {
        __escape = __obj.escape = function(value) {
          return ('' + value).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
        };
      }(function() {
        (function() {
          var user, _i, _len, _ref;
          __out.push('<!DOCTYPE html>\n<html lang="en">\n  <head>\n    <meta charset="utf-8">\n    <title>');
          __out.push(__sanitize(this.title));
          __out.push('</title>\n    <style>\n      body {font-family: "sans-serif"}\n      section, header {display: block}\n    </style>\n  </head>\n  <body>\n    <section>\n      <header>\n        <h1>');
          __out.push(__sanitize(this.title));
          __out.push('</h1>\n      </header>\n      ');
          if (this.inspired) {
            __out.push('\n        <p>Create a witty example</p>\n      ');
          } else {
            __out.push('\n        <p>Go meta</p>\n      ');
          }
          __out.push('\n      <ul>\n        ');
          _ref = this.users;
          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
            user = _ref[_i];
            __out.push('\n          <li>');
            __out.push(__sanitize(user.name));
            __out.push('</li>\n          <li><a href="mailto:');
            __out.push(__sanitize(user.email));
            __out.push('">');
            __out.push(__sanitize(user.email));
            __out.push('</a></li>\n        ');
          }
          __out.push('\n      </ul>\n    </section>\n  </body>\n</html>');
        }).call(this);

      }).call(__obj);
      __obj.safe = __objSafe, __obj.escape = __escape;
      return __out.join('');
      };

  var data = {
    title: 'test',
    inspired: false,
    users: [{
      email: 'house@gmail.com',
      name: 'house'
    }, {
      email: 'cuddy@gmail.com',
      name: 'cuddy'
    }, {
      email: 'wilson@gmail.com',
      name: 'wilson'
    }]
  };
</script>
<script src="http://dl.dropbox.com/u/5186182/funcd.js">
</script>
<script>
var funcd_template = function(t, data) {
    t.doctype(5);
    t.html({
      lang: 'en'
    }, function() {
      t.head(function() {
        t.meta({
          charset: 'utf-8'
        });
        t.title(data.title);
      });
      t.body(function() {
        t.section(function() {
          t.header(function() {
            t.h1(data.title);
          });
          if (data.inspired) {
            t.p('Create a witty example');
          } else {
            t.p('Go meta');
          }
          t.ul(function() {
            var user, _i, _len, _ref;
            _ref = data.users;
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
              user = _ref[_i];
              t.li(user.name);
              t.li(function() {
                t.a({
                  href: "mailto:" + user.email
                }, user.email);
              });
            }
          });
        });
      });
    });

};
</script>
    

Preparation code output

<script> var template = function anonymous(data) { var a, b, body, em, h1, head, header, html, i, ins, li, p, s, section, style, th, title, u, ul, font, tt, hr, meta; a = function() { return __ck.tag('a', arguments); }; b = function() { return __ck.tag('b', arguments); }; body = function() { return __ck.tag('body', arguments); }; em = function() { return __ck.tag('em', arguments); }; h1 = function() { return __ck.tag('h1', arguments); }; head = function() { return __ck.tag('head', arguments); }; header = function() { return __ck.tag('header', arguments); }; html = function() { return __ck.tag('html', arguments); }; i = function() { return __ck.tag('i', arguments); }; ins = function() { return __ck.tag('ins', arguments); }; li = function() { return __ck.tag('li', arguments); }; p = function() { return __ck.tag('p', arguments); }; s = function() { return __ck.tag('s', arguments); }; section = function() { return __ck.tag('section', arguments); }; style = function() { return __ck.tag('style', arguments); }; th = function() { return __ck.tag('th', arguments); }; title = function() { return __ck.tag('title', arguments); }; u = function() { return __ck.tag('u', arguments); }; ul = function() { return __ck.tag('ul', arguments); }; font = function() { return __ck.tag('font', arguments); }; tt = function() { return __ck.tag('tt', arguments); }; hr = function() { return __ck.tag('hr', arguments); }; meta = function() { return __ck.tag('meta', arguments); }; var __slice = Array.prototype.slice; var __hasProp = Object.prototype.hasOwnProperty; var __bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; }; var __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; var __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (this[i] === item) return i; } return -1; }; var coffeescript, comment, doctype, h, ie, tag, text, yield, __ck, _ref, _ref2; if (data == null) { data = {}; } if ((_ref = data.format) == null) { data.format = false; } if ((_ref2 = data.autoescape) == null) { data.autoescape = false; } __ck = { buffer: [], esc: function(txt) { if (data.autoescape) { return h(txt); } else { return String(txt); } }, tabs: 0, repeat: function(string, count) { return Array(count + 1).join(string); }, indent: function() { if (data.format) { return text(this.repeat(' ', this.tabs)); } }, tag: function(name, args) { var combo, i, _i, _len; combo = [name]; for (_i = 0, _len = args.length; _i < _len; _i++) { i = args[_i]; combo.push(i); } return tag.apply(data, combo); }, render_idclass: function(str) { var c, classes, i, id, _i, _j, _len, _len2, _ref3; classes = []; _ref3 = str.split('.'); for (_i = 0, _len = _ref3.length; _i < _len; _i++) { i = _ref3[_i]; if (__indexOf.call(i, '#') >= 0) { id = i.replace('#', ''); } else { if (i !== '') { classes.push(i); } } } if (id) { text(" id=\"" + id + "\""); } if (classes.length > 0) { text(" class=\""); for (_j = 0, _len2 = classes.length; _j < _len2; _j++) { c = classes[_j]; if (c !== classes[0]) { text(' '); } text(c); } return text('"'); } }, render_attrs: function(obj, prefix) { var k, v, _results; if (prefix == null) { prefix = ''; } _results = []; for (k in obj) { v = obj[k]; if (typeof v === 'boolean' && v) { v = k; } if (typeof v === 'function') { v = "(" + v + ").call(this);"; } _results.push(typeof v === 'object' && !(v instanceof Array) ? this.render_attrs(v, prefix + k + '-') : v ? text(" " + (prefix + k) + "=\"" + (this.esc(v)) + "\"") : void 0); } return _results; }, render_contents: function(contents) { var result; switch (typeof contents) { case 'string': case 'number': case 'boolean': return text(this.esc(contents)); case 'function': if (data.format) { text('\n'); } this.tabs++; result = contents.call(data); if (typeof result === 'string') { this.indent(); text(this.esc(result)); if (data.format) { text('\n'); } } this.tabs--; return this.indent(); } }, render_tag: function(name, idclass, attrs, contents) { this.indent(); text("<" + name); if (idclass) { this.render_idclass(idclass); } if (attrs) { this.render_attrs(attrs); } if (__indexOf.call(this.self_closing, name) >= 0) { text(' />'); if (data.format) { text('\n'); } } else { text('>'); this.render_contents(contents); text("</" + name + ">"); if (data.format) { text('\n'); } } return null; } }; tag = function() { var a, args, attrs, contents, idclass, name, _i, _len; name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; for (_i = 0, _len = args.length; _i < _len; _i++) { a = args[_i]; switch (typeof a) { case 'function': contents = a; break; case 'object': attrs = a; break; case 'number': case 'boolean': contents = a; break; case 'string': if (args.length === 1) { contents = a; } else { if (a === args[0]) { idclass = a; } else { contents = a; } } } } return __ck.render_tag(name, idclass, attrs, contents); }; yield = function(f) { var old_buffer, temp_buffer; temp_buffer = []; old_buffer = __ck.buffer; __ck.buffer = temp_buffer; f(); __ck.buffer = old_buffer; return temp_buffer.join(''); }; h = function(txt) { return String(txt).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); }; doctype = function(type) { if (type == null) { type = 'default'; } text(__ck.doctypes[type]); if (data.format) { return text('\n'); } }; text = function(txt) { __ck.buffer.push(String(txt)); return null; }; comment = function(cmt) { text("<!--" + cmt + "-->"); if (data.format) { return text('\n'); } }; coffeescript = function(param) { switch (typeof param) { case 'function': return script("" + __ck.coffeescript_helpers + "(" + param + ").call(this);"); case 'string': return script({ type: 'text/coffeescript' }, function() { return param; }); case 'object': param.type = 'text/coffeescript'; return script(param); } }; ie = function(condition, contents) { __ck.indent(); text("<!--[if " + condition + "]>"); __ck.render_contents(contents); text("<![endif]-->"); if (data.format) { return text('\n'); } }; __ck.doctypes = { "5": "<!DOCTYPE html>", "default": "<!DOCTYPE html>", "xml": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>", "transitional": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">", "strict": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">", "frameset": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">", "1.1": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">", "basic": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML Basic 1.1//EN\" \"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd\">", "mobile": "<!DOCTYPE html PUBLIC \"-//WAPFORUM//DTD XHTML Mobile 1.2//EN\" \"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd\">", "ce": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"ce-html-1.0-transitional.dtd\">" }; __ck.coffeescript_helpers = "var __slice = Array.prototype.slice;var __hasProp = Object.prototype.hasOwnProperty;var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };var __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };var __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (this[i] === item) return i; } return -1; };"; __ck.self_closing = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr", "basefont", "frame"]; (function() { doctype(5); html({ lang: 'en' }, function() { head(function() { meta({ charset: 'utf-8' }); title(this.title); return style('body {font-family: "sans-serif"}\nsection, header {display: block}'); }); return body(function() { return section(function() { header(function() { return h1(this.title); }); if (this.inspired) { p('Create a witty example'); } else { p('Go meta'); } return ul(function() { var user, _i, _len, _ref, _results; _ref = this.users; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { user = _ref[_i]; li(user.name); _results.push(li(function() { return a({ href: "mailto:" + user.email }, function() { return user.email; }); })); } return _results; }); }); }); }); }).call(data); return __ck.buffer.join(''); }; var optimized = function anonymous(data) { __ck = { buffer: '' }; text = function(txt) { if (typeof txt === 'string' || txt instanceof String) { __ck.buffer += txt; } else if (typeof txt === 'number' || txt instanceof Number) { __ck.buffer += String(txt); } }; h = function(txt) { var escaped; if (typeof txt === 'string' || txt instanceof String) { escaped = txt.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); } else { escaped = txt; } return escaped; }; yield = function(f) { var temp_buffer = ''; var old_buffer = __ck.buffer; __ck.buffer = temp_buffer; f(); temp_buffer = __ck.buffer; __ck.buffer = old_buffer; return temp_buffer; }; ((function() { text("<!DOCTYPE html>"); text('<html lang="en">'); text(function() { text("<head>"); text(function() { text('<meta charset="utf-8" />'); text("<title>"); text(this.title); text("</title>"); return function() { text("<style>"); text('body {font-family: "sans-serif"}\nsection, header {display: block}'); text("</style>"); }.call(data); }.call(data)); text("</head>"); return function() { text("<body>"); text(function() { return function() { text("<section>"); text(function() { text("<header>"); text(function() { return function() { text("<h1>"); text(this.title); text("</h1>"); }.call(data); }.call(data)); text("</header>"); if (this.inspired) { text("<p>"); text("Create a witty example"); text("</p>"); } else { text("<p>"); text("Go meta"); text("</p>"); } return function() { text("<ul>"); text(function() { var user, _i, _len, _ref, _results; _ref = this.users; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { user = _ref[_i]; text("<li>"); text(user.name); text("</li>"); _results.push(function() { text("<li>"); text(function() { return function() { text('<a href="'); text("mailto:" + user.email); text('">'); text(function() { return user.email; }.call(data)); text("</a>"); }.call(data); }.call(data)); text("</li>"); }.call(data)); } return _results; }.call(data)); text("</ul>"); }.call(data); }.call(data)); text("</section>"); }.call(data); }.call(data)); text("</body>"); }.call(data); }.call(data)); text("</html>"); })).call(data); return __ck.buffer; }; var eco_template = function(__obj) { if (!__obj) __obj = {}; var __out = [], __capture = function(callback) { var out = __out, result; __out = []; callback.call(this); result = __out.join(''); __out = out; return __safe(result); }, __sanitize = function(value) { if (value && value.ecoSafe) { return value; } else if (typeof value !== 'undefined' && value != null) { return __escape(value); } else { return ''; } }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; __safe = __obj.safe = function(value) { if (value && value.ecoSafe) { return value; } else { if (!(typeof value !== 'undefined' && value != null)) value = ''; var result = new String(value); result.ecoSafe = true; return result; } }; if (!__escape) { __escape = __obj.escape = function(value) { return ('' + value).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); }; }(function() { (function() { var user, _i, _len, _ref; __out.push('<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="utf-8">\n <title>'); __out.push(__sanitize(this.title)); __out.push('</title>\n <style>\n body {font-family: "sans-serif"}\n section, header {display: block}\n </style>\n </head>\n <body>\n <section>\n <header>\n <h1>'); __out.push(__sanitize(this.title)); __out.push('</h1>\n </header>\n '); if (this.inspired) { __out.push('\n <p>Create a witty example</p>\n '); } else { __out.push('\n <p>Go meta</p>\n '); } __out.push('\n <ul>\n '); _ref = this.users; for (_i = 0, _len = _ref.length; _i < _len; _i++) { user = _ref[_i]; __out.push('\n <li>'); __out.push(__sanitize(user.name)); __out.push('</li>\n <li><a href="mailto:'); __out.push(__sanitize(user.email)); __out.push('">'); __out.push(__sanitize(user.email)); __out.push('</a></li>\n '); } __out.push('\n </ul>\n </section>\n </body>\n</html>'); }).call(this); }).call(__obj); __obj.safe = __objSafe, __obj.escape = __escape; return __out.join(''); }; var data = { title: 'test', inspired: false, users: [{ email: 'house@gmail.com', name: 'house' }, { email: 'cuddy@gmail.com', name: 'cuddy' }, { email: 'wilson@gmail.com', name: 'wilson' }] }; </script> <script src="http://dl.dropbox.com/u/5186182/funcd.js"> </script> <script> var funcd_template = function(t, data) { t.doctype(5); t.html({ lang: 'en' }, function() { t.head(function() { t.meta({ charset: 'utf-8' }); t.title(data.title); }); t.body(function() { t.section(function() { t.header(function() { t.h1(data.title); }); if (data.inspired) { t.p('Create a witty example'); } else { t.p('Go meta'); } t.ul(function() { var user, _i, _len, _ref; _ref = data.users; for (_i = 0, _len = _ref.length; _i < _len; _i++) { user = _ref[_i]; t.li(user.name); t.li(function() { t.a({ href: "mailto:" + user.email }, user.email); }); } }); }); }); }); }; </script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
Compiled template
template(data);
pending…
Optimized template
optimized(data);
pending…
Eco template
eco_template(data);
pending…
funcd
Funcd.render(funcd_template, data);
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL.

0 Comments