SlideShare a Scribd company logo
1 of 61
Download to read offline
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-)servicesRafael Winterhalter
 
Capacity Planning for Linux Systems
Capacity Planning for Linux SystemsCapacity Planning for Linux Systems
Capacity Planning for Linux SystemsRodrigo Campos
 
Behavior driven oop
Behavior driven oopBehavior driven oop
Behavior driven oopPiyush Verma
 
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++17Bartlomiej 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 StackKeitaSugiyama1
 
Performance evaluation of Linux Discard Support
Performance evaluation of Linux Discard SupportPerformance evaluation of Linux Discard Support
Performance evaluation of Linux Discard SupportLukáš 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 slidesDmitry 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 InternalsESUG
 
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 ColumnStoreMariaDB plc
 
12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine12 Monkeys Inside JS Engine
12 Monkeys Inside JS EngineChengHui Weng
 
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 EnvironmentRaimonds Simanovskis
 
Apache con na_2013_updated_2016
Apache con na_2013_updated_2016Apache con na_2013_updated_2016
Apache con na_2013_updated_2016muellerc
 
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 Pythonkwatch
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアルkwatch
 
なんでもID
なんでもIDなんでもID
なんでもIDkwatch
 
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 Pythonkwatch
 
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/Mercurialkwatch
 
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

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 

Recently uploaded (20)

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 

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