SlideShare a Scribd company logo
1 of 25
Download to read offline
tDiary Anniversary Party
High Performance tDiary
tDiary は遅い
stackprof
tDiary endpoint for stackprof
index.rb
(snip)
if encoding_error.empty?
@cgi = cgi
else
@cgi = CGI::new(accept_charset: 'shift_jis')
@cgi.params = cgi.params
end
request = TDiary::Request.new( ENV, @cgi )
status, headers, body = TDiary::Dispatcher.index.dispatch_cgi( request, @cgi )
TDiary::Dispatcher.send_headers( status, headers )
::Rack::Handler::CGI.send_body(body)
(snip)
tDiary endpoint for stackprof
index.rb
(snip)
if encoding_error.empty?
@cgi = cgi
else
@cgi = CGI::new(accept_charset: 'shift_jis')
@cgi.params = cgi.params
end
request = TDiary::Request.new( ENV, @cgi )
status = headers = body = nil
StackProf.run(mode: :cpu, out: “path/to/stackprof-cpu-#{Time.now.to_i}.dump”) do
status, headers, body = TDiary::Dispatcher.index.dispatch_cgi( request, @cgi )
end
TDiary::Dispatcher.send_headers( status, headers )
::Rack::Handler::CGI.send_body(body)
(snip)
StackProf results
==================================
Mode: cpu(1000)
Samples: 36989 (6.05% miss rate)
GC: 5689 (15.38%)
==================================
TOTAL (pct) SAMPLES (pct) FRAME
3293 (8.9%) 3290 (8.9%) Dalli::Server#deserialize
1497 (4.0%) 1497 (4.0%) block (2 levels) in TDiary::IO::Default#calendar
2733 (7.4%) 1371 (3.7%) REXML::Attributes#get_attribute
2549 (6.9%) 1145 (3.1%) REXML::Parsers::BaseParser#pull_event
2532 (6.8%) 931 (2.5%) ERB::Compiler::SimpleScanner2#scan
1861 (5.0%) 928 (2.5%) REXML::Element#root
1601 (4.3%) 865 (2.3%) block in ERB::Compiler#compile
838 (2.3%) 838 (2.3%) block in REXML::Document#doctype
8633 (23.3%) 619 (1.7%) REXML::Element#namespace
603 (1.6%) 603 (1.6%) REXML::Source#match
612 (1.7%) 594 (1.6%) block in TDiary::Plugin#load_plugin
5071 (13.7%) 579 (1.6%) TDiary::IO::Default#transaction
739 (2.0%) 572 (1.5%) CGI::Util#unescape
564 (1.5%) 535 (1.4%) REXML::Text.check
(snip)
Dalli::Server#deserialize
memcached サーバーに cache を保存するやつ
サーバー1台だと不要なので File + PStore に戻す
REXML::*
amazon.rb や flickr.rb の response をパース
native extension の Oga に書き換える
benchmark-ips
benchmark-ips
require 'benchmark/ips'
Benchmark.ips do |x|
xml = File.read('../spec/fixtures/jpB00H91KK26.xml')
require_relative '../misc/plugin/amazon'
x.report('rexml') do
item = AmazonItem.new(xml)
amazon_detail_html( item )
end
x.report('oga') do
require 'oga'
item = AmazonItem.new(xml, :oga)
amazon_detail_html(item)
end
end
Results of Improvement
% ruby benchmark_amazon_plugin.rb
Warming up --------------------------------------
rexml 2.000 i/100ms
oga 14.000 i/100ms
Calculating -------------------------------------
rexml 37.678 (±15.9%) i/s - 182.000 in 5.013022s
oga 159.203 (±13.2%) i/s - 784.000 in 5.034065s
4.2 times faster!!1
Migration strategy for REXML and Oga
class AmazonItem
def initialize(xml, parser = :rexml)
@parser = parser
if parser == :oga
doc = Oga.parse_xml(xml)
@item = doc.xpath('*/*/Item')[0]
else
doc = REXML::Document::new( REXML::Source::new( xml ) ).root
@item = doc.elements.to_a( '*/Item' )[0]
end
end
def nodes(path)
if @parser == :oga
@item.xpath(path)
else
@item.elements.to_a(path)
end
end
end
IO::Default#calendar
日記データをすべて参照して月のリストを作るメソッ
ド、リクエストの度に毎回呼ばれている
tDiary のテストのしにくさよ…
ひたすら stub/mock module を用意する
class DummyTDiary
attr_accessor :conf
def initialize
@conf = DummyConf.new
@conf.data_path = TDiary.root + "/tmp/"
end
def ignore_parser_cache
false
end
end
class DummyConf
attr_accessor :data_path
def cache_path
TDiary.root + "/tmp/cache"
end
def options
{}
end
def style
"wiki"
end
end
module TDiary
PATH = File::dirname( __FILE__ ).untaint
class << self
def root
File.expand_path(File.join(library_root, '..'))
end
def library_root
File.expand_path('..', __FILE__)
end
def server_root
Dir.pwd.untaint
end
end
end
benchmark-ips(2)
conf = DummyConf.new
conf.data_path = TDiary.root + '/tmp/data/'
diary = DummyTDiary.new
diary.conf = conf
io = TDiary::IO::Default.new(diary)
require 'benchmark/ips'
Benchmark.ips do |x|
x.report('calendar') do
io.calendar
end
x.report('calendar2') do
io.calendar2
end
end
Improvement for calendar
def calendar
calendar = {}
Dir["#{@data_path}????"].sort.each do |dir|
next unless %r[/d{4}$] =~ dir
Dir["#{dir.untaint}/??????.td2"].sort.each do |file|
year, month = file.scan( %r[/(d{4})(dd).td2$] )[0]
next unless year
calendar[year] = [] unless calendar[year]
calendar[year] << month
end
end
calendar
end def calendar2
calendar = {}
Dir["#{@data_path}????/??????.td2"].sort.each do |file|
if file =~ /(d{4})(d{2}).td2$/
calendar[$1] = [] unless calendar[$1]
calendar[$1] << $2
end
end
calendar
end
benchmark-ips
% ruby benchmark_io_default.rb
Warming up --------------------------------------
calendar 16.000 i/100ms
calendar2 22.000 i/100ms
Calculating -------------------------------------
calendar 195.073 (±14.9%) i/s - 960.000 in 5.070197s
calendar2 237.695 (±13.9%) i/s - 1.166k in 5.039136s
1.21 times faster!!1
Results and Conclusion
StackProf results(2)
==================================
Mode: cpu(1000)
Samples: 15391 (14.55% miss rate)
GC: 2682 (17.43%)
==================================
TOTAL (pct) SAMPLES (pct) FRAME
43760 (284.3%) 3371 (21.9%) TDiary::Plugin#load_plugin
1014 (6.6%) 1014 (6.6%) PStore#load
487 (3.2%) 487 (3.2%) <module:Flickr>
445 (2.9%) 445 (2.9%) TDiary::Configuration#[]
768 (5.0%) 384 (2.5%) TDiary::IO::Default#calendar
374 (2.4%) 374 (2.4%) CGI::Util#unescape
614 (4.0%) 339 (2.2%) TDiary::RefererManager#add_referer
335 (2.2%) 335 (2.2%) TDiary::Plugin#add_header_proc
293 (1.9%) 293 (1.9%) <module:Category>
1798 (11.7%) 276 (1.8%) Kernel#open
224 (1.5%) 224 (1.5%) TDiary::Plugin#enable_js
220 (1.4%) 220 (1.4%) TDiary::Plugin#add_conf_proc
1620 (10.5%) 212 (1.4%) TDiary::IO::Default#transaction
1213 (7.9%) 199 (1.3%) PStore#load_data
(snip)
速くなったかな…
CGI::Util.unescape
Ruby 2.4.0 で nobu が C ext で書き換えたので速くな
る。2.2/2.3 向けに gem にバックポートしてもいいか
も。
flickr プラグイン
amazon プラグイン同様に REXML が遅いので Oga に
書き換える予定
TDiary::Plugin#load_plugin
プラグインを全部読み込んで eval してるアレ…
プラグイン機構を変えるとかして速くしたいなあ…
まずは eval の仕組みを利用すれば速くできそう
→プラグインを File.read する度に eval するのではな
く全てを File.read して繋げてから eval すると速そう
速かった
Warming up --------------------------------------
multi-eval 283.000 i/100ms
single-eval 565.000 i/100ms
Calculating -------------------------------------
multi-eval 2.918k (±14.8%) i/s - 14.433k in 5.100649s
single-eval 5.444k (±18.5%) i/s - 25.990k in 5.015969s
Benchmark.ips do |x|
o = Object.new
x.report('multi-eval') do
o.instance_eval("def a; puts 'a'; end")
(snip)
o.instance_eval("def z; puts 'z'; end")
end
x.report('single-eval') do
o.instance_eval("def a; puts 'a'; end; (snip) def z; puts 'z'; end")
end
end
tDiary 楽しい!!1
15年やってもまだまだ hack しがいがある!!1

More Related Content

What's hot

RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueGleicon Moraes
 
PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0Tim Bunce
 
Lightweight wrapper for Hive on Amazon EMR
Lightweight wrapper for Hive on Amazon EMRLightweight wrapper for Hive on Amazon EMR
Lightweight wrapper for Hive on Amazon EMRShinji Tanaka
 
Gemification plan of Standard Library on Ruby
Gemification plan of Standard Library on RubyGemification plan of Standard Library on Ruby
Gemification plan of Standard Library on RubyHiroshi SHIBATA
 
Perl at SkyCon'12
Perl at SkyCon'12Perl at SkyCon'12
Perl at SkyCon'12Tim Bunce
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in PerlLaurent Dami
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2rubyMarc Chung
 
Roll Your Own API Management Platform with nginx and Lua
Roll Your Own API Management Platform with nginx and LuaRoll Your Own API Management Platform with nginx and Lua
Roll Your Own API Management Platform with nginx and LuaJon Moore
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 
Python在豆瓣的应用
Python在豆瓣的应用Python在豆瓣的应用
Python在豆瓣的应用Qiangning Hong
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mrubyHiroshi SHIBATA
 
Lua tech talk
Lua tech talkLua tech talk
Lua tech talkLocaweb
 
Application Logging in the 21st century - 2014.key
Application Logging in the 21st century - 2014.keyApplication Logging in the 21st century - 2014.key
Application Logging in the 21st century - 2014.keyTim Bunce
 
Perl Memory Use - LPW2013
Perl Memory Use - LPW2013Perl Memory Use - LPW2013
Perl Memory Use - LPW2013Tim Bunce
 
Python高级编程(二)
Python高级编程(二)Python高级编程(二)
Python高级编程(二)Qiangning Hong
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principlesPerl Careers
 
Devinsampa nginx-scripting
Devinsampa nginx-scriptingDevinsampa nginx-scripting
Devinsampa nginx-scriptingTony Fabeen
 
On UnQLite
On UnQLiteOn UnQLite
On UnQLitecharsbar
 

What's hot (20)

RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message Queue
 
PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0
 
Lightweight wrapper for Hive on Amazon EMR
Lightweight wrapper for Hive on Amazon EMRLightweight wrapper for Hive on Amazon EMR
Lightweight wrapper for Hive on Amazon EMR
 
Gemification plan of Standard Library on Ruby
Gemification plan of Standard Library on RubyGemification plan of Standard Library on Ruby
Gemification plan of Standard Library on Ruby
 
Perl at SkyCon'12
Perl at SkyCon'12Perl at SkyCon'12
Perl at SkyCon'12
 
Nodejs - A quick tour (v6)
Nodejs - A quick tour (v6)Nodejs - A quick tour (v6)
Nodejs - A quick tour (v6)
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in Perl
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
 
Roll Your Own API Management Platform with nginx and Lua
Roll Your Own API Management Platform with nginx and LuaRoll Your Own API Management Platform with nginx and Lua
Roll Your Own API Management Platform with nginx and Lua
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
Python在豆瓣的应用
Python在豆瓣的应用Python在豆瓣的应用
Python在豆瓣的应用
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mruby
 
Lua tech talk
Lua tech talkLua tech talk
Lua tech talk
 
DevOps with Fabric
DevOps with FabricDevOps with Fabric
DevOps with Fabric
 
Application Logging in the 21st century - 2014.key
Application Logging in the 21st century - 2014.keyApplication Logging in the 21st century - 2014.key
Application Logging in the 21st century - 2014.key
 
Perl Memory Use - LPW2013
Perl Memory Use - LPW2013Perl Memory Use - LPW2013
Perl Memory Use - LPW2013
 
Python高级编程(二)
Python高级编程(二)Python高级编程(二)
Python高级编程(二)
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principles
 
Devinsampa nginx-scripting
Devinsampa nginx-scriptingDevinsampa nginx-scripting
Devinsampa nginx-scripting
 
On UnQLite
On UnQLiteOn UnQLite
On UnQLite
 

Viewers also liked

How to Begin Developing Ruby Core
How to Begin Developing Ruby CoreHow to Begin Developing Ruby Core
How to Begin Developing Ruby CoreHiroshi SHIBATA
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mrubyHiroshi SHIBATA
 
GitHub Enterprise with GMO Pepabo
GitHub Enterprise with GMO PepaboGitHub Enterprise with GMO Pepabo
GitHub Enterprise with GMO PepaboHiroshi SHIBATA
 
Large-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 MinutesLarge-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 MinutesHiroshi SHIBATA
 
How to test code with mruby
How to test code with mrubyHow to test code with mruby
How to test code with mrubyHiroshi SHIBATA
 
How to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHow to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHiroshi SHIBATA
 
成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略Hiroshi SHIBATA
 
mruby で mackerel のプラグインを作るはなし
mruby で mackerel のプラグインを作るはなしmruby で mackerel のプラグインを作るはなし
mruby で mackerel のプラグインを作るはなしHiroshi SHIBATA
 
The story of language development
The story of language developmentThe story of language development
The story of language developmentHiroshi SHIBATA
 
Advanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesAdvanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesHiroshi SHIBATA
 
Usecase examples of Packer
Usecase examples of Packer Usecase examples of Packer
Usecase examples of Packer Hiroshi SHIBATA
 
技術的負債との付き合い方
技術的負債との付き合い方技術的負債との付き合い方
技術的負債との付き合い方Hiroshi SHIBATA
 

Viewers also liked (13)

How to Begin Developing Ruby Core
How to Begin Developing Ruby CoreHow to Begin Developing Ruby Core
How to Begin Developing Ruby Core
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mruby
 
GitHub Enterprise with GMO Pepabo
GitHub Enterprise with GMO PepaboGitHub Enterprise with GMO Pepabo
GitHub Enterprise with GMO Pepabo
 
Large-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 MinutesLarge-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 Minutes
 
How DSL works on Ruby
How DSL works on RubyHow DSL works on Ruby
How DSL works on Ruby
 
How to test code with mruby
How to test code with mrubyHow to test code with mruby
How to test code with mruby
 
How to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHow to Begin to Develop Ruby Core
How to Begin to Develop Ruby Core
 
成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略
 
mruby で mackerel のプラグインを作るはなし
mruby で mackerel のプラグインを作るはなしmruby で mackerel のプラグインを作るはなし
mruby で mackerel のプラグインを作るはなし
 
The story of language development
The story of language developmentThe story of language development
The story of language development
 
Advanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesAdvanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutes
 
Usecase examples of Packer
Usecase examples of Packer Usecase examples of Packer
Usecase examples of Packer
 
技術的負債との付き合い方
技術的負債との付き合い方技術的負債との付き合い方
技術的負債との付き合い方
 

Similar to High Performance tDiary

All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkBen Scofield
 
SparkR - Play Spark Using R (20160909 HadoopCon)
SparkR - Play Spark Using R (20160909 HadoopCon)SparkR - Play Spark Using R (20160909 HadoopCon)
SparkR - Play Spark Using R (20160909 HadoopCon)wqchen
 
Fluentd unified logging layer
Fluentd   unified logging layerFluentd   unified logging layer
Fluentd unified logging layerKiyoto Tamura
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Improving go-git performance
Improving go-git performanceImproving go-git performance
Improving go-git performancesource{d}
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slidesharetomcopeland
 
Design Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonDesign Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonManageIQ
 
파이썬 개발환경 구성하기의 끝판왕 - Docker Compose
파이썬 개발환경 구성하기의 끝판왕 - Docker Compose파이썬 개발환경 구성하기의 끝판왕 - Docker Compose
파이썬 개발환경 구성하기의 끝판왕 - Docker Composeraccoony
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 
Curscatalyst
CurscatalystCurscatalyst
CurscatalystKar Juan
 
Architecting Alive Apps
Architecting Alive AppsArchitecting Alive Apps
Architecting Alive AppsJorge Ortiz
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony TechniquesKris Wallsmith
 
Debugging of (C)Python applications
Debugging of (C)Python applicationsDebugging of (C)Python applications
Debugging of (C)Python applicationsRoman Podoliaka
 
Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model Perforce
 
Keeping Spark on Track: Productionizing Spark for ETL
Keeping Spark on Track: Productionizing Spark for ETLKeeping Spark on Track: Productionizing Spark for ETL
Keeping Spark on Track: Productionizing Spark for ETLDatabricks
 
Oracle database - Get external data via HTTP, FTP and Web Services
Oracle database - Get external data via HTTP, FTP and Web ServicesOracle database - Get external data via HTTP, FTP and Web Services
Oracle database - Get external data via HTTP, FTP and Web ServicesKim Berg Hansen
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 

Similar to High Performance tDiary (20)

All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
SparkR - Play Spark Using R (20160909 HadoopCon)
SparkR - Play Spark Using R (20160909 HadoopCon)SparkR - Play Spark Using R (20160909 HadoopCon)
SparkR - Play Spark Using R (20160909 HadoopCon)
 
Fluentd unified logging layer
Fluentd   unified logging layerFluentd   unified logging layer
Fluentd unified logging layer
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Improving go-git performance
Improving go-git performanceImproving go-git performance
Improving go-git performance
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshare
 
Design Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonDesign Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron Patterson
 
Drupal 8 migrate!
Drupal 8 migrate!Drupal 8 migrate!
Drupal 8 migrate!
 
파이썬 개발환경 구성하기의 끝판왕 - Docker Compose
파이썬 개발환경 구성하기의 끝판왕 - Docker Compose파이썬 개발환경 구성하기의 끝판왕 - Docker Compose
파이썬 개발환경 구성하기의 끝판왕 - Docker Compose
 
Drupal 7 database api
Drupal 7 database api Drupal 7 database api
Drupal 7 database api
 
DataMapper
DataMapperDataMapper
DataMapper
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
Curscatalyst
CurscatalystCurscatalyst
Curscatalyst
 
Architecting Alive Apps
Architecting Alive AppsArchitecting Alive Apps
Architecting Alive Apps
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Debugging of (C)Python applications
Debugging of (C)Python applicationsDebugging of (C)Python applications
Debugging of (C)Python applications
 
Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model
 
Keeping Spark on Track: Productionizing Spark for ETL
Keeping Spark on Track: Productionizing Spark for ETLKeeping Spark on Track: Productionizing Spark for ETL
Keeping Spark on Track: Productionizing Spark for ETL
 
Oracle database - Get external data via HTTP, FTP and Web Services
Oracle database - Get external data via HTTP, FTP and Web ServicesOracle database - Get external data via HTTP, FTP and Web Services
Oracle database - Get external data via HTTP, FTP and Web Services
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 

More from Hiroshi SHIBATA

Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Deep dive into Ruby's require - RubyConf Taiwan 2023
Deep dive into Ruby's require - RubyConf Taiwan 2023Deep dive into Ruby's require - RubyConf Taiwan 2023
Deep dive into Ruby's require - RubyConf Taiwan 2023Hiroshi SHIBATA
 
How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?Hiroshi SHIBATA
 
How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?Hiroshi SHIBATA
 
Ruby コミッターと歩む Ruby を用いたプロダクト開発
Ruby コミッターと歩む Ruby を用いたプロダクト開発Ruby コミッターと歩む Ruby を用いたプロダクト開発
Ruby コミッターと歩む Ruby を用いたプロダクト開発Hiroshi SHIBATA
 
Why ANDPAD commit Ruby and RubyKaigi?
Why ANDPAD commit Ruby and RubyKaigi?Why ANDPAD commit Ruby and RubyKaigi?
Why ANDPAD commit Ruby and RubyKaigi?Hiroshi SHIBATA
 
RailsGirls から始める エンジニアリングはじめの一歩
RailsGirls から始める エンジニアリングはじめの一歩RailsGirls から始める エンジニアリングはじめの一歩
RailsGirls から始める エンジニアリングはじめの一歩Hiroshi SHIBATA
 
How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?Hiroshi SHIBATA
 
The details of CI/CD environment for Ruby
The details of CI/CD environment for RubyThe details of CI/CD environment for Ruby
The details of CI/CD environment for RubyHiroshi SHIBATA
 
Dependency Resolution with Standard Libraries
Dependency Resolution with Standard LibrariesDependency Resolution with Standard Libraries
Dependency Resolution with Standard LibrariesHiroshi SHIBATA
 
Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3Hiroshi SHIBATA
 
The Future of library dependency management of Ruby
 The Future of library dependency management of Ruby The Future of library dependency management of Ruby
The Future of library dependency management of RubyHiroshi SHIBATA
 
Ruby Security the Hard Way
Ruby Security the Hard WayRuby Security the Hard Way
Ruby Security the Hard WayHiroshi SHIBATA
 
OSS Security the hard way
OSS Security the hard wayOSS Security the hard way
OSS Security the hard wayHiroshi SHIBATA
 
The Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyThe Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyHiroshi SHIBATA
 
The Future of Dependency Management for Ruby
The Future of Dependency Management for RubyThe Future of Dependency Management for Ruby
The Future of Dependency Management for RubyHiroshi SHIBATA
 
The Future of Bundled Bundler
The Future of Bundled BundlerThe Future of Bundled Bundler
The Future of Bundled BundlerHiroshi SHIBATA
 
Productive Organization with Ruby
Productive Organization with RubyProductive Organization with Ruby
Productive Organization with RubyHiroshi SHIBATA
 

More from Hiroshi SHIBATA (20)

Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Deep dive into Ruby's require - RubyConf Taiwan 2023
Deep dive into Ruby's require - RubyConf Taiwan 2023Deep dive into Ruby's require - RubyConf Taiwan 2023
Deep dive into Ruby's require - RubyConf Taiwan 2023
 
How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?
 
How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?
 
Ruby コミッターと歩む Ruby を用いたプロダクト開発
Ruby コミッターと歩む Ruby を用いたプロダクト開発Ruby コミッターと歩む Ruby を用いたプロダクト開発
Ruby コミッターと歩む Ruby を用いたプロダクト開発
 
Why ANDPAD commit Ruby and RubyKaigi?
Why ANDPAD commit Ruby and RubyKaigi?Why ANDPAD commit Ruby and RubyKaigi?
Why ANDPAD commit Ruby and RubyKaigi?
 
RailsGirls から始める エンジニアリングはじめの一歩
RailsGirls から始める エンジニアリングはじめの一歩RailsGirls から始める エンジニアリングはじめの一歩
RailsGirls から始める エンジニアリングはじめの一歩
 
How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?
 
The details of CI/CD environment for Ruby
The details of CI/CD environment for RubyThe details of CI/CD environment for Ruby
The details of CI/CD environment for Ruby
 
Dependency Resolution with Standard Libraries
Dependency Resolution with Standard LibrariesDependency Resolution with Standard Libraries
Dependency Resolution with Standard Libraries
 
Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3
 
The Future of library dependency management of Ruby
 The Future of library dependency management of Ruby The Future of library dependency management of Ruby
The Future of library dependency management of Ruby
 
Ruby Security the Hard Way
Ruby Security the Hard WayRuby Security the Hard Way
Ruby Security the Hard Way
 
OSS Security the hard way
OSS Security the hard wayOSS Security the hard way
OSS Security the hard way
 
The Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyThe Future of library dependency manageement of Ruby
The Future of library dependency manageement of Ruby
 
The Future of Dependency Management for Ruby
The Future of Dependency Management for RubyThe Future of Dependency Management for Ruby
The Future of Dependency Management for Ruby
 
The Future of Bundled Bundler
The Future of Bundled BundlerThe Future of Bundled Bundler
The Future of Bundled Bundler
 
What's new in RubyGems3
What's new in RubyGems3What's new in RubyGems3
What's new in RubyGems3
 
Productive Organization with Ruby
Productive Organization with RubyProductive Organization with Ruby
Productive Organization with Ruby
 
Gems on Ruby
Gems on RubyGems on Ruby
Gems on Ruby
 

Recently uploaded

The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
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
 
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
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
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
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
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
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
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
 

Recently uploaded (20)

The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
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
 
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
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
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
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
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
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
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...
 

High Performance tDiary

  • 1. tDiary Anniversary Party High Performance tDiary
  • 4. tDiary endpoint for stackprof index.rb (snip) if encoding_error.empty? @cgi = cgi else @cgi = CGI::new(accept_charset: 'shift_jis') @cgi.params = cgi.params end request = TDiary::Request.new( ENV, @cgi ) status, headers, body = TDiary::Dispatcher.index.dispatch_cgi( request, @cgi ) TDiary::Dispatcher.send_headers( status, headers ) ::Rack::Handler::CGI.send_body(body) (snip)
  • 5. tDiary endpoint for stackprof index.rb (snip) if encoding_error.empty? @cgi = cgi else @cgi = CGI::new(accept_charset: 'shift_jis') @cgi.params = cgi.params end request = TDiary::Request.new( ENV, @cgi ) status = headers = body = nil StackProf.run(mode: :cpu, out: “path/to/stackprof-cpu-#{Time.now.to_i}.dump”) do status, headers, body = TDiary::Dispatcher.index.dispatch_cgi( request, @cgi ) end TDiary::Dispatcher.send_headers( status, headers ) ::Rack::Handler::CGI.send_body(body) (snip)
  • 6. StackProf results ================================== Mode: cpu(1000) Samples: 36989 (6.05% miss rate) GC: 5689 (15.38%) ================================== TOTAL (pct) SAMPLES (pct) FRAME 3293 (8.9%) 3290 (8.9%) Dalli::Server#deserialize 1497 (4.0%) 1497 (4.0%) block (2 levels) in TDiary::IO::Default#calendar 2733 (7.4%) 1371 (3.7%) REXML::Attributes#get_attribute 2549 (6.9%) 1145 (3.1%) REXML::Parsers::BaseParser#pull_event 2532 (6.8%) 931 (2.5%) ERB::Compiler::SimpleScanner2#scan 1861 (5.0%) 928 (2.5%) REXML::Element#root 1601 (4.3%) 865 (2.3%) block in ERB::Compiler#compile 838 (2.3%) 838 (2.3%) block in REXML::Document#doctype 8633 (23.3%) 619 (1.7%) REXML::Element#namespace 603 (1.6%) 603 (1.6%) REXML::Source#match 612 (1.7%) 594 (1.6%) block in TDiary::Plugin#load_plugin 5071 (13.7%) 579 (1.6%) TDiary::IO::Default#transaction 739 (2.0%) 572 (1.5%) CGI::Util#unescape 564 (1.5%) 535 (1.4%) REXML::Text.check (snip)
  • 7. Dalli::Server#deserialize memcached サーバーに cache を保存するやつ サーバー1台だと不要なので File + PStore に戻す
  • 8. REXML::* amazon.rb や flickr.rb の response をパース native extension の Oga に書き換える
  • 10. benchmark-ips require 'benchmark/ips' Benchmark.ips do |x| xml = File.read('../spec/fixtures/jpB00H91KK26.xml') require_relative '../misc/plugin/amazon' x.report('rexml') do item = AmazonItem.new(xml) amazon_detail_html( item ) end x.report('oga') do require 'oga' item = AmazonItem.new(xml, :oga) amazon_detail_html(item) end end
  • 11. Results of Improvement % ruby benchmark_amazon_plugin.rb Warming up -------------------------------------- rexml 2.000 i/100ms oga 14.000 i/100ms Calculating ------------------------------------- rexml 37.678 (±15.9%) i/s - 182.000 in 5.013022s oga 159.203 (±13.2%) i/s - 784.000 in 5.034065s 4.2 times faster!!1
  • 12. Migration strategy for REXML and Oga class AmazonItem def initialize(xml, parser = :rexml) @parser = parser if parser == :oga doc = Oga.parse_xml(xml) @item = doc.xpath('*/*/Item')[0] else doc = REXML::Document::new( REXML::Source::new( xml ) ).root @item = doc.elements.to_a( '*/Item' )[0] end end def nodes(path) if @parser == :oga @item.xpath(path) else @item.elements.to_a(path) end end end
  • 14. tDiary のテストのしにくさよ… ひたすら stub/mock module を用意する class DummyTDiary attr_accessor :conf def initialize @conf = DummyConf.new @conf.data_path = TDiary.root + "/tmp/" end def ignore_parser_cache false end end class DummyConf attr_accessor :data_path def cache_path TDiary.root + "/tmp/cache" end def options {} end def style "wiki" end end module TDiary PATH = File::dirname( __FILE__ ).untaint class << self def root File.expand_path(File.join(library_root, '..')) end def library_root File.expand_path('..', __FILE__) end def server_root Dir.pwd.untaint end end end
  • 15. benchmark-ips(2) conf = DummyConf.new conf.data_path = TDiary.root + '/tmp/data/' diary = DummyTDiary.new diary.conf = conf io = TDiary::IO::Default.new(diary) require 'benchmark/ips' Benchmark.ips do |x| x.report('calendar') do io.calendar end x.report('calendar2') do io.calendar2 end end
  • 16. Improvement for calendar def calendar calendar = {} Dir["#{@data_path}????"].sort.each do |dir| next unless %r[/d{4}$] =~ dir Dir["#{dir.untaint}/??????.td2"].sort.each do |file| year, month = file.scan( %r[/(d{4})(dd).td2$] )[0] next unless year calendar[year] = [] unless calendar[year] calendar[year] << month end end calendar end def calendar2 calendar = {} Dir["#{@data_path}????/??????.td2"].sort.each do |file| if file =~ /(d{4})(d{2}).td2$/ calendar[$1] = [] unless calendar[$1] calendar[$1] << $2 end end calendar end
  • 17. benchmark-ips % ruby benchmark_io_default.rb Warming up -------------------------------------- calendar 16.000 i/100ms calendar2 22.000 i/100ms Calculating ------------------------------------- calendar 195.073 (±14.9%) i/s - 960.000 in 5.070197s calendar2 237.695 (±13.9%) i/s - 1.166k in 5.039136s 1.21 times faster!!1
  • 19. StackProf results(2) ================================== Mode: cpu(1000) Samples: 15391 (14.55% miss rate) GC: 2682 (17.43%) ================================== TOTAL (pct) SAMPLES (pct) FRAME 43760 (284.3%) 3371 (21.9%) TDiary::Plugin#load_plugin 1014 (6.6%) 1014 (6.6%) PStore#load 487 (3.2%) 487 (3.2%) <module:Flickr> 445 (2.9%) 445 (2.9%) TDiary::Configuration#[] 768 (5.0%) 384 (2.5%) TDiary::IO::Default#calendar 374 (2.4%) 374 (2.4%) CGI::Util#unescape 614 (4.0%) 339 (2.2%) TDiary::RefererManager#add_referer 335 (2.2%) 335 (2.2%) TDiary::Plugin#add_header_proc 293 (1.9%) 293 (1.9%) <module:Category> 1798 (11.7%) 276 (1.8%) Kernel#open 224 (1.5%) 224 (1.5%) TDiary::Plugin#enable_js 220 (1.4%) 220 (1.4%) TDiary::Plugin#add_conf_proc 1620 (10.5%) 212 (1.4%) TDiary::IO::Default#transaction 1213 (7.9%) 199 (1.3%) PStore#load_data (snip)
  • 21. CGI::Util.unescape Ruby 2.4.0 で nobu が C ext で書き換えたので速くな る。2.2/2.3 向けに gem にバックポートしてもいいか も。
  • 22. flickr プラグイン amazon プラグイン同様に REXML が遅いので Oga に 書き換える予定
  • 23. TDiary::Plugin#load_plugin プラグインを全部読み込んで eval してるアレ… プラグイン機構を変えるとかして速くしたいなあ… まずは eval の仕組みを利用すれば速くできそう →プラグインを File.read する度に eval するのではな く全てを File.read して繋げてから eval すると速そう
  • 24. 速かった Warming up -------------------------------------- multi-eval 283.000 i/100ms single-eval 565.000 i/100ms Calculating ------------------------------------- multi-eval 2.918k (±14.8%) i/s - 14.433k in 5.100649s single-eval 5.444k (±18.5%) i/s - 25.990k in 5.015969s Benchmark.ips do |x| o = Object.new x.report('multi-eval') do o.instance_eval("def a; puts 'a'; end") (snip) o.instance_eval("def z; puts 'z'; end") end x.report('single-eval') do o.instance_eval("def a; puts 'a'; end; (snip) def z; puts 'z'; end") end end