 So hello everybody. I'm Akira from Japan. This is me on internet I'm a MATSD on github and a on the bar MATSD on Twitter, this is me on github As you see I'm on Rails team and I'm a Ruby committer Also, I'm a Hemel committer and that is why I'm talking about template engines and I've created a Ruby gem called Kaminari Also, I'm a organizer of Ruby Kaiji Ruby Kaiji. This is Ruby Kaiji This year we did a International Ruby conference in Japan called Ruby Kaiji like two months ago, I guess so if you missed the event there's a There are tons of slides and videos online. So please check them out. You can get them via that schedule link All right, and What's next? Asakusa.rb So this is a Local user group based on based in Tokyo We have a weekly meetup on every Ruby Tuesday So this time I came to San Diego for you Right, so it's it's your turn next. Please visit us in Tokyo and Come to a meetup. We'll We'll welcome your visit All right, so this start from erb Firstly, I want you to know that there's a Template engine specification in Ruby Which is called eRuby Have you heard about eRuby? Do you know what it is? eRuby stands for Embedded Ruby I'm not talking about in Ruby thing, but this is yet another embedded Ruby and This embedded Ruby does I'm sorry. This embedded Ruby is a spec for embedding Ruby code into a text file like HTML files this mRuby, I'm sorry, embedded Ruby was created by Matt and Shugo Maeda who is known as Matt's boss Actually asked Shugo-san and he said That the concept is based on eRuby. I mean ePurl so that eRuby spec was mainly stolen from Purl and There's yet another eRuby This eRuby has small art, right? So this eRuby is the referential in Implementation of eRuby written in C language this eRuby was Created by Shugo-san But unfortunately this eRuby is no more maintained and but instead we have eRuby Which you know very well eRuby is a pure Ruby implementation of eRuby. I mean eRuby and This is a included in Ruby package as a standard library eRuby was created by Masato Shiseki who's a legendary Ruby programmer who also created things like Linza and DRB A lot of these awesome libraries So as talking about eRuby, I see so many mistakes on books even on I think pickaxe like misspelling on eRuby. Don't spell eRuby like eR small b It used to be called eR small b, but it was renamed to full capital eRuby when becoming a Ruby standard library so as I said the eRuby is Implemented purely in Ruby which is actually only one file in the lib directory and Which has Approximately 1,000 lines of Ruby code It looks like a huge library, but actually Half of them are documents. So it's actually less than 500 lines It's quite small you can read it. So let me show you how to use eRuby This is the basic use is just eRuby eRuby.new give a template string into eRuby.new and call result method on the instance this will return the Embed Ruby embedded string like this pretty easy, right? So this is how we can embed Ruby code into the template of course, you know and This is how you can embed Ruby expressions as you know So How does this work? Let's see the implementation Firstly, I called eRuby.new this is what's going to happen when calling eRuby.new it creates a something called a compiler and Then the compiler compiles the given template into at sign src right, so Compiler.compile does this it creates a buffer thing and Then scans through the given template and splits the template into some tokens starting from this Bracket person sign and Then executes a some kind of command for each of those Token and then so I'm going to pick pick up one command called add portCMD here The implementation looks like this It it pushes into the buffer some string Pushes a little bit Ruby code string into the buffer And the former part Former part portCMD is a method and the latter part is a parameter then the portCMD is Actually Defined like this. It's a string on the bar erbout.concat this this becomes a Ruby command and the content dump The parameter it just dumps the string so the whole Hello code generates this Ruby code It prepares the buffer and pushes this erbout.concat.hello.dump Then evals the string Evals this string as a Ruby code so in total it erb.new.result executes something like this creates a erbout Instance and puts some code into that and then evals the buffer, right? Okay, so this is the basic usage of erb and How do we actually use erb on our applications? I guess this is the major risk case we use templating template file put template file on the application directory and To generate HTML response body text And I'm sure mainly on Ruby on Rails So in Ruby on Rails What renders templates is Rendering template is done in this component named action view So how does action view renders? This is the simplest code that can Kick action view to render the template You can just create the instance of action view base and call the render method Render method is implemented like this Again, it compiles the given template and and Sends something into Some kind of object called view Sends some kind of methods name. It's a ton of magic, but this is what's happening So Let's look into the compile Definition this is how action view compiles the template Like It compiles only once. I mean if it's the compilation is done it sets the flag to true so that it never runs again and Actual compile is like this I'm not gonna explain in detail, but it it creates some Ruby method the whole Ruby deaf deaf expression and Executes it right afterwards. So Compile to compile template Means to define a method Which is generated from the template onto something called mod and then Then what's happening next is handler called self. This is handler dot call call Calls ERB implementation dot new dot source This is of course as you see ERB dot new dot source which returns the Generated Ruby string and then it Puts the generated spring into this method body, right? so In summary what action view render does is it defines a Ruby method on the view object and the method body generated by ERB dot new dot source ERB Source returns the Ruby code string to be valid This is how This was how ERB resolve evals the string, but so yeah ERB source looks like this, but in rails case We don't eval, but to find a method, but it works the same basically So the short summary is again the template compiles into that a Ruby method and it compiles only once Compile compilation overhead is not at all a big deal. I mean it happens only once on the production application so what really matters is Not the compilation speed, but the code execution speed that Execution speed performance of the Generated Ruby code Right So report reprise again, this is This is the definition of ERB hand handler call so It's not directly calling erb.new, but something called class dot erb Implementation dot new what is ERB implementation It's actually said to something else called a rubies not erb It's defaulted to a rubies So what is this erubis thing? Erbis is Yet another pure Ruby implementative erubi It's not in this ten a library, but it's a gem which is called by a Japanese guy called named Makoto kuata You can find the source code of this gem here and According to its read me it's Very fast almost three times faster than erb awesome, and This has some unique features like it auto escapes The I mean it can auto escape the template Strings and it supports Ruby on Rails etc etc So I said erubis is a Implementation of erubi, but actually It's it's not pure purely You erubi compatible it's it's erb compatible, but it has something Else plus erubi that the general erubi erubi specification right Like auto escaping or Ruby on Rails support such things So why does action view use a ruby spider fault? Why not erb? I want to use something stanzord right so I want to use erb It should be quite easy because it's configurable Okay, let's try It's easy with this patch So actually I tried this And run the rake test For the action view component And yes it fails I saw a massive massive number of This kind of syntax errors so um I looked at the error code and actually this simple Ruby template causes syntax error on erb It works on erubis, but doesn't work on erb Why doesn't it? because This is not allowed in erubi erubi spec. This is not the Regular erubi template Instead it should be written like this. Do you remember this? Before rails 3 we had to We could not add an equal time in front of form 4 or link 2 with block or What else? These kind of things these kind of method that takes a block Right, so this is the right way to Call The method with block in erubi spec but Rails somehow allows this It's a magic So Let's dig into the magic. How did things change in rails 2? Rails 2 style and rails 3 style Let's take a look at the rails repository this time So this was what happened at the very first commit It's a huge commit that That improves this rail security Sorry This introduced something called safe buffer and after this commit we could Like we could create safe string and unsafe string And the string objects Are regarded unsafe by default since this commit then In action view this commit adds These lines like it requires erubis and Uses erubis instead of erb erubis dot new right So why erubis because As you've seen on the readme Erubis had auto escaping support Rails needed this in order to Implement the Rail 3 auto escaping thing I guess some of you might remember this HTML escape in templates You need you had to put age onto each of the Possibly unsafe strings Or else your Your application might be unsecure Rails 1 and 2 used to be like this You could easily create unsafe applications so So the rails team changed the default string strings to be default Treated unsafe and automatically call This h method inside the framework And then and then cause Changed that hard-coded erubis Name class name into a variable So that you can configure And then someone else called josei changed its name into From erubis implementation to erb implementation despite This doesn't actually support erb so so rails Default template handle is erubis not erb because erubis has some original extensions in addition to erubi spec And the rails team liked it And thus we can now we cannot switch erb implementation back to erb I actually noticed this problem like two years ago before releasing ruby 2.0 and I actually asked the maintainer of erb That Isn't it possible to support rails extension like um erb to be rails compatible in ruby 2.0 He said yes, I'll try and he actually tried He tried to add some extension points to erb and he He investigated into the difference between erb and erubis But he gave up Because he didn't really like this part Um in action view block expression um so This code scans the template with this expression and does something And this was not acceptable for a second So what is this expression and why why is this problematic? Let's carefully take a look at This The regular expression This is how it's used The expression matches if the given um Token matches this expression It does something and If doesn't does not match it does something else Okay So the token can be something like this This this regular expression is for detecting if the token Includes a block Opening block or not So this becomes true if The token contains something like this form for do So let's try Let's try matching some ruby blocks These are all valid ruby block syntax, right? I tried this and I found actually some of these doesn't match It's buggy apparently this This regular expression is buggy so form for foo Without putting a space In front of the opening brace it works If you if you're familiar with ruby golf I'm sure you always write blocks like like this, but Action view doesn't accept this this code Action view does not regard this as a block And causes a syntax error But it's easy to fix I think s plus requires one or more spaces but in this case we We want to match these bottom two lines so It can be like this. It's easy Just one byte patch seems good now this expression becomes to match something else like Any string that ends with do matches this expression so now This expression regards A template like this as a block and causes another syntax error Which is weird so in summary I guess I would fix this particular case like I wrote another expression it can be It can be detected like a little bit longer expression, but I mean basically Trying to parse ruby in your ruby library is a wrong approach Having such ruby ruby parsing code other than ruby parser would be cause such weird bug This is I guess again wrong approach as this guy said The ruby parser is a nightmare so Don't deal with ruby parser unless you're in nobu right so That is why this syntax is not acceptable on the standard erb right anyway Now you see how erb works and the difference between erb and eruby. I mean erubist but anyway your difference between erb and erubis is not a big deal because We don't need use neither of them anyway and our choice is of course Hemel So chapter 2 What is hemel? Hemel is a templating haiku according to its read me I don't know what exactly means Templating haiku exactly means I suppose it means Just a short expression means That does a lot of work means a lot I think it's What the haiku means so Usages hemel This is how to output hello in hemel Hemel has a random method It's kind of similar to erb's result method This prints hello and hemel engine new actually parses the hemel template into a ruby code if you would like to see the ruby code instead of Executing it it has something like this It's equivalent to erb source I'm going to show you how it works Let's start at irb require Whoops I'm sorry I made it typo Did you mean hemel? Oh my god, what's this? Did you mean hemel? Oh my god, my console is so clever So smart I don't know what's happening here What's this? Can anyone please Explain what's happening on my console Can anyone please Anyone knows What is this? Raise your hand stand up Come up to the stage come on Well, all right One minute I'll give you one minute to introduce your product I know he He prepared his slide for the lightning talk yesterday but unfortunately He signed up late so he couldn't get the chance I tried to give him a chance All right The gem is called Did you mean so please Gem install this one Which should work this way? It's pretty useful Thank you Chigo How can I switch back? Can we win this? Chigo no And I forgot to do the demo Anyway, I'll skip the demo This would output Something like this Just for printing out hello Hello This is how erb Outputs hello And again, this is how hemel outputs Hello All right, okay Nice haiku So Seriously um I think we don't usually have to care what's happening inside the library, but Isn't this too much? It apparently looks Slow slow slow ruby code So I said compilation overhead doesn't matter, but The generated ruby code if the generated good ruby code looks like this. This does matter Right Let's prove if it's fast or slow So The benchmark um Let's start with the simplest benchmark It can be like this um, you can put the I mean you can define the ruby method onto any object In this case just object new and Define the generated ruby code as a method and call it put And the result I get this result the hemel code runs 26 times slower than erb1 In this micro benchmark but I think this is not the real use case because um action views are something more complex indeed So Let's see the actual rendering speed using action view right This this benchmark might be something more a little bit more realistic Um, it uses action view template for Executing the ruby methods And I get this result It's still hemel is still two two times slower than erb in this Benchmark version two But Actually, I skipped the template resolution code because it's uh It's actually slow in rails so What really happens when you in your rails application is Actually this um As I showed you in my previous slide action view base instance call the render method for the action view instance And in this benchmark I got this result on the real hello application And erb template render is like 20 percent Faster than hemel I guess this is like a real benchmark results So why is hemel slow? I have six more minutes. Okay. Why is hemel slow? So let's read the haiku The haiku consists of three parts Goshichi go and This is the three parts um, it prepares massive number of objects and generates hello code and Returns the buffer And you see apparently the setup part does something wrong So In this part we have many many Options that is given to hemel buffer new Yes, hemel has many options like this and Hemel Configures this option in runtime for each Hemel buffer objects I don't know why but it's also But who actually configures hemel in your application? Have you ever configured? Have you ever used or changed these? um Settings I guess nobody We don't need such a feature everyone use Uses default value, right? So let's just remove them Removing removing the option the code looks like this Much better, right The next one is hemel helpers which is You see at the very top it extends hemel helpers What is hemel helpers? So there's a module in the hemel source code and Yeah, it defines tons of helpers lovely helpers like it's actually hemel specific helper methods and which is Put into each hemel buffers But again Anyone have used it? I guess nobody again. So let's remove them And the next point is buffers You see many many buffer buffer buffer buffer actually this This hyco includes six buffers Six buffer variables just to print out hello. Why don't we just remove some of these? And make the code Look like this. It should be possible and um html safe As we're already using action view output buffer what and Why you have to like? escape in the ruby side The library does it so um We can the hemel should be um, totally completely depends on action view. I mean active support and action view and In that way the code could be much simpler Who uses hemel off rails? I'm sorry But The hemel on rails Can be like this much simpler that The buffer has concat method which takes if if the given string is unsafe then it escapes inside the concat method so I think this is the goal I want to make hemel as fast as possible and to change the final output to be like this But these changes would bring some incompatibilities So I'm not going to push these changes into the hemel master and but instead I'm willing to I'm I'm trying to create a my own hemel fork, which is called hemel x Unfortunately, hemel x is not finished yet. I hoped I I I plan to finish Implementing this until the this talk and I plan to Do the demonstration, but it's not finished yet It's not online yet I'm still working on it and hopefully I'm going to ship it soon But this is the current status It's still like pretty much slower than erb Actually 16 percent times slower than erb, but My my branch is already 50 percent faster than the original hemel I think this is a Not bad and I think I have Only have 30 30 seconds left So part three slim I've got I've got 30 seconds for slim slim is Looks like hemel It does automatic html escaping In my opinion, slim is actually slimmer than The current hemel master Okay Actually the slim coat is slim because it is built on some libraries like temple and tilt and it has less options. It has no lovely helpers temple is a template compilation framework It compiles the template into the express expression first and then compiles it into ruby code It's a very clever library tilt tilt is a generic interface to multiple ruby template engines which bridges over template engines and Like web servers and framework and such things So slim is awesome. Thank you slim for being a good competitor for a hemel developer So this is the end of my talk conclusion Now that I think you understand how erb and erubis and hemel works and Yes, hemel is slow and I'm going to improve hemel The my My version of hemel called hemel x is hopefully coming soon. So please stay tuned Thank you