SlideShare a Scribd company logo
PyconMini JP 2011




How to Create a High-Speed
Template Engine in Python
Python




makoto kuwata
http://www.kuwata-lab.com/
Profile
 @makotokuwata

 http://www.kwuata-lab.com/

 Ruby/PHP/Python programmer

 Creator of Erubis (*)

 Python4PHPer


                 (*) default template engine on Rails 3
Python Products
 Tenjin       : very fast temlate engine
 Kook         : task utility like Ant/Rake
 Benchmarker : a good friend for performance
 Oktest       : new-style testing library
Tenjin
 Very fast
                       	      	     	  	      	    	 
 One file, 2000 lines   	 
                       	 	 
 Full-featured         	 
                       	      	             	 
 Python 3 support

 Google App Engine

 Release 1.0 coming soon!

 http://www.kuwta-lab.com/tenjin/
Benchmark
                   Tenjin                                                   2660.1
                   Mako                                    1426.4
                   Jinja2                                 1257.6
             Templetor                           903.0
               Cheetah                    562.3
                 Django           114.2
                 Genshi           55.7
                       Kid        34.6
                              0          600       1200       1800   2400     3000

Python 2.5.5, MacOS X 10.6 (x86_64), 2GB                                    pages/sec
Tenjin 1.0.0, Mako 0.2.5, Jinja2 2.2.1, Templetor 0.32,
Cheetah 2.2.2, Django 1.1.0, Genshi 0.5.1, Kid 0.9.6
Benchmarks for
String Concatenation
append()
Benchmark                          pages/sec



  append()




             0   200   400   600       800     1000
extend()
Benchmark                           pages/sec



  append()
   extend()




              0   200   400   600       800     1000
StringIO
Benchmark                           pages/sec



  append()
   extend()
   StringIO




              0   200   400   600       800     1000
mmap
Benchmark                           pages/sec



  append()
   extend()
   StringIO
    mmap




              0   200   400   600       800     1000
Generator
Benchmark                           pages/sec



  append()
   extend()
   StringIO
     mmap
  generator




              0   200   400   600       800     1000
Slice
Benchmark                               pages/sec



    append()
     extend()
     StringIO
       mmap
    generator
     slice[-1:]
 slice[99999:]

                  0   200   400   600       800     1000
Bound method
Benchmark                                 pages/sec



       append()
        extend()
       StringIO
         mmap
      generator
       slice[-1:]
   slice[99999:]
extend() (bound)
                    0   200   400   600       800     1000
Summary
Fast
 bound method >= slice[] > extend()

Slow
 Generator > append() > mmap > StringIO
Try Benchmark Script
Step by Step to
Tune-up Template Code
HTML Template
Python Code
Benchmark                                                 pages/sec

  append (singleline)




                        0   2000   4000   6000   8000 10000 12000
Multiple Line String
      	 
                       	 

           	 

      	 
                            	 

 	              Eliminates method call
Benchmark                                                 pages/sec

  append (singleline)
   append (multiline)




                        0   2000   4000   6000   8000 10000 12000
From append() to extend()
     	 
                              	 	 



     	 
                                	 	 
 	 	 	 	 	 	 	 	 	 	 	 	 	 
 	 	 	 	 	 	 	 	 	 	 	 	 	             	 

Eliminates method call
Benchmark                                                 pages/sec

  append (singleline)
   append (multiline)
   extend (unbound)




                        0   2000   4000   6000   8000 10000 12000
Bound Method
 	 
                   	      	         	 
                   	      	         	 
                   	      	         	 

 	 
      	  	 
              	        	       	 
              	        	       	 
                      Eliminates
              	        	       	 
                    fetch method
Benchmark                                                 pages/sec

  append (singleline)
   append (multiline)
   extend (unbound)
     extend (bound)




                        0   2000   4000   6000   8000 10000 12000
str() function
     	 
           	       	          	 
 	 	       	       	 
 	 	       	       	                 	 

     	 
           	       	               	 
 	 	       	             	 
 	 	       	             	                	 

  Necessary in Python!
Benchmark                                                 pages/sec

  append (singleline)
   append (multiline)
   extend (unbound)
     extend (bound)

        extend + str




                        0   2000   4000   6000   8000 10000 12000
Local Variable
     	 

 	 	 	 	 	 	 	 	 	 
 	 	 	 	 	 	 	 	 	      	 

     	                Local var is faster than
          	  	          global/build-in var
Benchmark                                                 pages/sec

  append (singleline)
   append (multiline)
   extend (unbound)
     extend (bound)

        extend + str
   extend + _str=str




                        0   2000   4000   6000   8000 10000 12000
Format ('%' operator)
     	 
                              	                     	 
                 	                      	 
                 	                      	                	 

     	 
                                             Delete all str() call
                                              by '%' operator
Benchmark                                                 pages/sec

  append (singleline)
   append (multiline)
   extend (unbound)
     extend (bound)

        extend + str
   extend + _str=str
   append + format




                        0   2000   4000   6000   8000 10000 12000
None => Empty String
     	                     Converts None
       	                   to empty string
Benchmark                                                   pages/sec

    append (singleline)
     append (multiline)
     extend (unbound)
       extend (bound)

           extend + str
     extend + _str=str
      append + format
       extend + to_str
extend + _to_str=to_str




                          0   2000   4000   6000   8000 10000 12000
Escape HTML
Benchmark                                                   pages/sec

    append (singleline)
     append (multiline)
     extend (unbound)
       extend (bound)

           extend + str
     extend + _str=str
      append + format
       extend + to_str
extend + _to_str=to_str

     escape_html + str
  escape_html + to_str



                          0   2000   4000   6000   8000 10000 12000
C Extension
                               Implemented in C
     	 
          	           	          	         	 

                        	 	 
 	 	 	 	 	 	 	 	 	 
 	 	 	 	 	 	 	 	 	                    	 
     	 
                        	 	 
 	 	 	 	 	 	 	 	 	 
 	 	 	 	 	 	 	 	 	                    	 

     webext: http://pypi.python.org/pypi/Webext/
Benchmark                                                      pages/sec

        append (singleline)
         append (multiline)
         extend (unbound)
           extend (bound)

               extend + str
         extend + _str=str
          append + format
           extend + to_str
    extend + _to_str=to_str

        escape_html + str
     escape_html + to_str
webext.escape_html, to_str
     webext.escape_html
                              0   2000   4000   6000   8000 10000 12000
Extreme join()
             Not escaped                          Be escaped
          if index % 2 == 0                   if index % 2 == 1
     	                                        (no need to call
          	  	                                escape_html() !)
Benchmark


  Not implemeted yet...
Summary
String concatenation is not a bottleneck
  extend() & join() are enough fast

Bottleneck is str() and escape_html()
 join() should call str() internally

 C Extension (webext) is great
Other Topics
Google says...

  ... The major web applications we
  have surveyed have indicated that
  they bottleneck primarily on
  template systems, ...
                                    Django?
  http://code.google.com/p/unladen-swallow/wiki/ProjectPlan
Case Study #1
  http://www.myweightracker.com/
  Switch from Django template to Tenjin

        M, C, Network, etc...                  Django


                                                           ed
        M, C, Network, etc...                           Spe !
                                                      pp Up
                                                    A
                                                      30%
https://groups.google.com/group/kuwata-lab-products/
browse_thread/thread/b50877a9c56d64c9/60f77b5c9b9f5238
Case Study #2
   Ruby on Rails 1.2
   Remove helper methods by preprocessing

  M, C, Network, etc...                       Helper Methods

         template engine
                                                                ed
  M, C, Network, etc...                                   pp Spe !
                                                        A      Up
                                                         1 00%

http://jp.rubyist.net/magazine/?0021-Erubis
Components of View Layer
                              Just one of them

                   Template
Important for       Engine           More Important
performance!
                                    for performance!



        Helper                 Cache
       Functions              Mechanism
Preprocessing in Tenjin

    Convert

              	         	        	 

    Execute        Called everytime
Preprocessing in Tenjin

              Call function
    Convert
              in this stage

                    	 

    Execute   Func call removed
Python v.s. Others
   plTenjin (Perl)                                  12108.0

pyTenjin+Webext              4179.7
                                                        he
                                                      st !
 phpTenjin (PHP)         2788.0
                                               Pe rl i ion
                                                 ha  mp
pyTenjin (Python)        2682.9                C
  rbTenjin (Ruby)        2634.8

                     0       2500     5000   7500   10000   12500

                                                     pages/sec
Why Perl is so Fast?
 No need to call str(val) nor val.toString()
 Bytecode op for string concatenation
C Ext v.s. Pure Script
        plTenjin                                                  Pure Perl
       MobaSiF                                            C Ext
Template::Toolkit       C Ext

pyTenjin+Webext                     Python + C Ext
         pyTenjin               Pure Python
        Cheetah         C Ext                        No need to impl
                                                       engine in C
         rbTenjin             Pure Ruby              (except helpers)
           eruby         C Ext
                    0      2500     5000      7500     10000    12500

                                                               pages/sec
Summary
View layer components
 Template engine, Helper functions, and
 Cache mechanism
No need to implement engine in C
(except helper functions)
Perl is great
Django temlate engine sucks
Appendix
 Tenjin: fast & full-featured template engine
  http://www.kuwata-lab.com/tenjin/

 Webext: C extension for escape_html()
  http://pypi.python.org/pypi/Webext/

 Benchmarker: a utility for benchmarking
  http://pypi.python.org/pypi/Benchmarker/
Appendix
 C              Ruby
     http://www.kuwata-lab.com/presen/rubykaigi2007.pdf
     http://jp.rubyist.net/magazine/?0022-FasterThanC

 Java               LL
     http://www.kuwata-lab.com/presen/LL2007LT.pdf


     http://jp.rubyist.net/magazine/?0024-TemplateSystem
     http://jp.rubyist.net/magazine/?0024-TemplateSystem2
thank you

More Related Content

Similar to How to Create a High-Speed Template Engine in Python

Monitoring distributed (micro-)services
Monitoring distributed (micro-)servicesMonitoring distributed (micro-)services
Monitoring distributed (micro-)services
Rafael Winterhalter
 
Capacity Planning for Linux Systems
Capacity Planning for Linux SystemsCapacity Planning for Linux Systems
Capacity Planning for Linux Systems
Rodrigo Campos
 
Behavior driven oop
Behavior driven oopBehavior driven oop
Behavior driven oop
Piyush Verma
 
Qemu JIT Code Generator and System Emulation
Qemu JIT Code Generator and System EmulationQemu JIT Code Generator and System Emulation
Qemu JIT Code Generator and System Emulation
National Cheng Kung University
 
Let's talks about string operations in C++17
Let's talks about string operations in C++17Let's talks about string operations in C++17
Let's talks about string operations in C++17
Bartlomiej Filipek
 
Grow and Shrink - Dynamically Extending the Ruby VM Stack
Grow and Shrink - Dynamically Extending the Ruby VM StackGrow and Shrink - Dynamically Extending the Ruby VM Stack
Grow and Shrink - Dynamically Extending the Ruby VM Stack
KeitaSugiyama1
 
Performance evaluation of Linux Discard Support
Performance evaluation of Linux Discard SupportPerformance evaluation of Linux Discard Support
Performance evaluation of Linux Discard Support
Lukáš Czerner
 
Bottlenecks, Bottlenecks, and more Bottlenecks: Lessons Learned from 2 Years ...
Bottlenecks, Bottlenecks, and more Bottlenecks: Lessons Learned from 2 Years ...Bottlenecks, Bottlenecks, and more Bottlenecks: Lessons Learned from 2 Years ...
Bottlenecks, Bottlenecks, and more Bottlenecks: Lessons Learned from 2 Years ...Enkitec
 
Accelerated Windows Debugging 3 training public slides
Accelerated Windows Debugging 3 training public slidesAccelerated Windows Debugging 3 training public slides
Accelerated Windows Debugging 3 training public slides
Dmitry Vostokov
 
Database Sharding the Right Way: Easy, Reliable, and Open source - HighLoad++...
Database Sharding the Right Way: Easy, Reliable, and Open source - HighLoad++...Database Sharding the Right Way: Easy, Reliable, and Open source - HighLoad++...
Database Sharding the Right Way: Easy, Reliable, and Open source - HighLoad++...
CUBRID
 
Pharo Optimising JIT Internals
Pharo Optimising JIT InternalsPharo Optimising JIT Internals
Pharo Optimising JIT Internals
ESUG
 
Python在豆瓣的应用
Python在豆瓣的应用Python在豆瓣的应用
Python在豆瓣的应用
Qiangning Hong
 
White Paper: xDesign Online Editor & API Performance Benchmark Summary
White Paper: xDesign Online Editor & API Performance Benchmark Summary   White Paper: xDesign Online Editor & API Performance Benchmark Summary
White Paper: xDesign Online Editor & API Performance Benchmark Summary
EMC
 
Big Data Analytics with MariaDB ColumnStore
Big Data Analytics with MariaDB ColumnStoreBig Data Analytics with MariaDB ColumnStore
Big Data Analytics with MariaDB ColumnStore
MariaDB plc
 
12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine
ChengHui Weng
 
Extending Io Scalability
Extending Io ScalabilityExtending Io Scalability
Extending Io Scalability
The Linux Foundation
 
Profiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production EnvironmentProfiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production Environment
Raimonds Simanovskis
 
Apache con na_2013_updated_2016
Apache con na_2013_updated_2016Apache con na_2013_updated_2016
Apache con na_2013_updated_2016
muellerc
 
Apache Con NA 2013
Apache Con NA 2013Apache Con NA 2013
Apache Con NA 2013muellerc
 

Similar to How to Create a High-Speed Template Engine in Python (20)

Monitoring distributed (micro-)services
Monitoring distributed (micro-)servicesMonitoring distributed (micro-)services
Monitoring distributed (micro-)services
 
Capacity Planning for Linux Systems
Capacity Planning for Linux SystemsCapacity Planning for Linux Systems
Capacity Planning for Linux Systems
 
Behavior driven oop
Behavior driven oopBehavior driven oop
Behavior driven oop
 
Qemu JIT Code Generator and System Emulation
Qemu JIT Code Generator and System EmulationQemu JIT Code Generator and System Emulation
Qemu JIT Code Generator and System Emulation
 
Let's talks about string operations in C++17
Let's talks about string operations in C++17Let's talks about string operations in C++17
Let's talks about string operations in C++17
 
Grow and Shrink - Dynamically Extending the Ruby VM Stack
Grow and Shrink - Dynamically Extending the Ruby VM StackGrow and Shrink - Dynamically Extending the Ruby VM Stack
Grow and Shrink - Dynamically Extending the Ruby VM Stack
 
Performance evaluation of Linux Discard Support
Performance evaluation of Linux Discard SupportPerformance evaluation of Linux Discard Support
Performance evaluation of Linux Discard Support
 
Bottlenecks, Bottlenecks, and more Bottlenecks: Lessons Learned from 2 Years ...
Bottlenecks, Bottlenecks, and more Bottlenecks: Lessons Learned from 2 Years ...Bottlenecks, Bottlenecks, and more Bottlenecks: Lessons Learned from 2 Years ...
Bottlenecks, Bottlenecks, and more Bottlenecks: Lessons Learned from 2 Years ...
 
Accelerated Windows Debugging 3 training public slides
Accelerated Windows Debugging 3 training public slidesAccelerated Windows Debugging 3 training public slides
Accelerated Windows Debugging 3 training public slides
 
Database Sharding the Right Way: Easy, Reliable, and Open source - HighLoad++...
Database Sharding the Right Way: Easy, Reliable, and Open source - HighLoad++...Database Sharding the Right Way: Easy, Reliable, and Open source - HighLoad++...
Database Sharding the Right Way: Easy, Reliable, and Open source - HighLoad++...
 
Pharo Optimising JIT Internals
Pharo Optimising JIT InternalsPharo Optimising JIT Internals
Pharo Optimising JIT Internals
 
Python在豆瓣的应用
Python在豆瓣的应用Python在豆瓣的应用
Python在豆瓣的应用
 
White Paper: xDesign Online Editor & API Performance Benchmark Summary
White Paper: xDesign Online Editor & API Performance Benchmark Summary   White Paper: xDesign Online Editor & API Performance Benchmark Summary
White Paper: xDesign Online Editor & API Performance Benchmark Summary
 
Big Data Analytics with MariaDB ColumnStore
Big Data Analytics with MariaDB ColumnStoreBig Data Analytics with MariaDB ColumnStore
Big Data Analytics with MariaDB ColumnStore
 
12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine
 
Extending Io Scalability
Extending Io ScalabilityExtending Io Scalability
Extending Io Scalability
 
Profiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production EnvironmentProfiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production Environment
 
Apache con na_2013_updated_2016
Apache con na_2013_updated_2016Apache con na_2013_updated_2016
Apache con na_2013_updated_2016
 
NoSQLを知る
NoSQLを知るNoSQLを知る
NoSQLを知る
 
Apache Con NA 2013
Apache Con NA 2013Apache Con NA 2013
Apache Con NA 2013
 

More from kwatch

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Python
kwatch
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアル
kwatch
 
なんでもID
なんでもIDなんでもID
なんでもID
kwatch
 
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
kwatch
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
kwatch
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
kwatch
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?
kwatch
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
kwatch
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
kwatch
 
PHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するPHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較する
kwatch
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
kwatch
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
kwatch
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
kwatch
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門
kwatch
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurial
kwatch
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -
kwatch
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた
kwatch
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"kwatch
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラム
kwatch
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジン
kwatch
 

More from kwatch (20)

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Python
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアル
 
なんでもID
なんでもIDなんでもID
なんでもID
 
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
 
PHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するPHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較する
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurial
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラム
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジン
 

Recently uploaded

Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 

Recently uploaded (20)

Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 

How to Create a High-Speed Template Engine in Python

  • 1. PyconMini JP 2011 How to Create a High-Speed Template Engine in Python Python makoto kuwata http://www.kuwata-lab.com/
  • 2. Profile @makotokuwata http://www.kwuata-lab.com/ Ruby/PHP/Python programmer Creator of Erubis (*) Python4PHPer (*) default template engine on Rails 3
  • 3. Python Products Tenjin : very fast temlate engine Kook : task utility like Ant/Rake Benchmarker : a good friend for performance Oktest : new-style testing library
  • 4. Tenjin Very fast One file, 2000 lines Full-featured Python 3 support Google App Engine Release 1.0 coming soon! http://www.kuwta-lab.com/tenjin/
  • 5. Benchmark Tenjin 2660.1 Mako 1426.4 Jinja2 1257.6 Templetor 903.0 Cheetah 562.3 Django 114.2 Genshi 55.7 Kid 34.6 0 600 1200 1800 2400 3000 Python 2.5.5, MacOS X 10.6 (x86_64), 2GB pages/sec Tenjin 1.0.0, Mako 0.2.5, Jinja2 2.2.1, Templetor 0.32, Cheetah 2.2.2, Django 1.1.0, Genshi 0.5.1, Kid 0.9.6
  • 8. Benchmark pages/sec append() 0 200 400 600 800 1000
  • 10. Benchmark pages/sec append() extend() 0 200 400 600 800 1000
  • 12. Benchmark pages/sec append() extend() StringIO 0 200 400 600 800 1000
  • 13. mmap
  • 14. Benchmark pages/sec append() extend() StringIO mmap 0 200 400 600 800 1000
  • 16. Benchmark pages/sec append() extend() StringIO mmap generator 0 200 400 600 800 1000
  • 17. Slice
  • 18. Benchmark pages/sec append() extend() StringIO mmap generator slice[-1:] slice[99999:] 0 200 400 600 800 1000
  • 20. Benchmark pages/sec append() extend() StringIO mmap generator slice[-1:] slice[99999:] extend() (bound) 0 200 400 600 800 1000
  • 21. Summary Fast bound method >= slice[] > extend() Slow Generator > append() > mmap > StringIO
  • 23. Step by Step to Tune-up Template Code
  • 26. Benchmark pages/sec append (singleline) 0 2000 4000 6000 8000 10000 12000
  • 27. Multiple Line String Eliminates method call
  • 28. Benchmark pages/sec append (singleline) append (multiline) 0 2000 4000 6000 8000 10000 12000
  • 29. From append() to extend() Eliminates method call
  • 30. Benchmark pages/sec append (singleline) append (multiline) extend (unbound) 0 2000 4000 6000 8000 10000 12000
  • 31. Bound Method Eliminates fetch method
  • 32. Benchmark pages/sec append (singleline) append (multiline) extend (unbound) extend (bound) 0 2000 4000 6000 8000 10000 12000
  • 33. str() function Necessary in Python!
  • 34. Benchmark pages/sec append (singleline) append (multiline) extend (unbound) extend (bound) extend + str 0 2000 4000 6000 8000 10000 12000
  • 35. Local Variable Local var is faster than global/build-in var
  • 36. Benchmark pages/sec append (singleline) append (multiline) extend (unbound) extend (bound) extend + str extend + _str=str 0 2000 4000 6000 8000 10000 12000
  • 37. Format ('%' operator) Delete all str() call by '%' operator
  • 38. Benchmark pages/sec append (singleline) append (multiline) extend (unbound) extend (bound) extend + str extend + _str=str append + format 0 2000 4000 6000 8000 10000 12000
  • 39. None => Empty String Converts None to empty string
  • 40. Benchmark pages/sec append (singleline) append (multiline) extend (unbound) extend (bound) extend + str extend + _str=str append + format extend + to_str extend + _to_str=to_str 0 2000 4000 6000 8000 10000 12000
  • 42. Benchmark pages/sec append (singleline) append (multiline) extend (unbound) extend (bound) extend + str extend + _str=str append + format extend + to_str extend + _to_str=to_str escape_html + str escape_html + to_str 0 2000 4000 6000 8000 10000 12000
  • 43. C Extension Implemented in C webext: http://pypi.python.org/pypi/Webext/
  • 44. Benchmark pages/sec append (singleline) append (multiline) extend (unbound) extend (bound) extend + str extend + _str=str append + format extend + to_str extend + _to_str=to_str escape_html + str escape_html + to_str webext.escape_html, to_str webext.escape_html 0 2000 4000 6000 8000 10000 12000
  • 45. Extreme join() Not escaped Be escaped if index % 2 == 0 if index % 2 == 1 (no need to call escape_html() !)
  • 46. Benchmark Not implemeted yet...
  • 47. Summary String concatenation is not a bottleneck extend() & join() are enough fast Bottleneck is str() and escape_html() join() should call str() internally C Extension (webext) is great
  • 49. Google says... ... The major web applications we have surveyed have indicated that they bottleneck primarily on template systems, ... Django? http://code.google.com/p/unladen-swallow/wiki/ProjectPlan
  • 50. Case Study #1 http://www.myweightracker.com/ Switch from Django template to Tenjin M, C, Network, etc... Django ed M, C, Network, etc... Spe ! pp Up A 30% https://groups.google.com/group/kuwata-lab-products/ browse_thread/thread/b50877a9c56d64c9/60f77b5c9b9f5238
  • 51. Case Study #2 Ruby on Rails 1.2 Remove helper methods by preprocessing M, C, Network, etc... Helper Methods template engine ed M, C, Network, etc... pp Spe ! A Up 1 00% http://jp.rubyist.net/magazine/?0021-Erubis
  • 52. Components of View Layer Just one of them Template Important for Engine More Important performance! for performance! Helper Cache Functions Mechanism
  • 53. Preprocessing in Tenjin Convert Execute Called everytime
  • 54. Preprocessing in Tenjin Call function Convert in this stage Execute Func call removed
  • 55. Python v.s. Others plTenjin (Perl) 12108.0 pyTenjin+Webext 4179.7 he st ! phpTenjin (PHP) 2788.0 Pe rl i ion ha mp pyTenjin (Python) 2682.9 C rbTenjin (Ruby) 2634.8 0 2500 5000 7500 10000 12500 pages/sec
  • 56. Why Perl is so Fast? No need to call str(val) nor val.toString() Bytecode op for string concatenation
  • 57. C Ext v.s. Pure Script plTenjin Pure Perl MobaSiF C Ext Template::Toolkit C Ext pyTenjin+Webext Python + C Ext pyTenjin Pure Python Cheetah C Ext No need to impl engine in C rbTenjin Pure Ruby (except helpers) eruby C Ext 0 2500 5000 7500 10000 12500 pages/sec
  • 58. Summary View layer components Template engine, Helper functions, and Cache mechanism No need to implement engine in C (except helper functions) Perl is great Django temlate engine sucks
  • 59. Appendix Tenjin: fast & full-featured template engine http://www.kuwata-lab.com/tenjin/ Webext: C extension for escape_html() http://pypi.python.org/pypi/Webext/ Benchmarker: a utility for benchmarking http://pypi.python.org/pypi/Benchmarker/
  • 60. Appendix C Ruby http://www.kuwata-lab.com/presen/rubykaigi2007.pdf http://jp.rubyist.net/magazine/?0022-FasterThanC Java LL http://www.kuwata-lab.com/presen/LL2007LT.pdf http://jp.rubyist.net/magazine/?0024-TemplateSystem http://jp.rubyist.net/magazine/?0024-TemplateSystem2