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

Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 

Recently uploaded (20)

Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 

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