Browse files

erb.rb: Generate static string with opt_str_uminus

to skip object allocation for static string.

We can't always enable frozen_string_literal pragma because we can't
freeze string literals embedded by user for backward compatibility.
So we need to use fstring for each static string.

Since adding ".freeze" to string literals in #content_dump is slow
on compiling, I used unary "-" operator instead.

benchmark/bm_app_erb_render.rb: Added rendering-only benchmark to
test rendering performance on production environment.

This benchmark is created to reproduce the behavior on Sinatra (Tilt).
Thus it doesn't use ERB#result to skip parsing compiled code.
It doesn't use ERB#def_method too to regard `title` and `content` as
local variables. If we use #def_method, `title` and `content` needs
to be method call. I wanted to avoid it.

This patch's benchmark results is:

* Before

app_erb_render  1.250
app_erb 0.704

* After

app_erb_render  1.066
app_erb 0.686

This patch optimizes rendering performance (app_erb_render) without
spoiling (total of rendering +) compiling performance (app_erb).

git-svn-id: svn+ssh:// b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information...
k0kubun committed May 26, 2017
1 parent 7348e2c commit 0e6776d7526ece11c707fd67cc57313144fc86a9
Showing with 27 additions and 1 deletion.
  1. +26 −0 benchmark/bm_app_erb_render.rb
  2. +1 −1 lib/erb.rb
@@ -0,0 +1,26 @@
require 'erb'
data =
max = 1_500_000
title = "hello world!"
content = "hello world!\n" * 10
src = "def self.render(title, content); #{}; end"
mod =
mod.instance_eval(src, "(ERB)")
max.times do
mod.render(title, content)
<head> <%= title %> </head>
<h1> <%= title %> </h1>
<%= content %>
@@ -589,7 +589,7 @@ def content_dump(s) # :nodoc:
def add_put_cmd(out, content)
out.push("#{@put_cmd} #{content_dump(content)}")
out.push("#{@put_cmd} -#{content_dump(content)}")
def add_insert_cmd(out, content)

0 comments on commit 0e6776d

Please sign in to comment.