Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Tokyo Ruby Kaigi
Search
Aaron Patterson
May 28, 2016
Technology
5
3.4k
Tokyo Ruby Kaigi
My talk from Tokyo Ruby Kaigi
Aaron Patterson
May 28, 2016
Tweet
Share
More Decks by Aaron Patterson
See All by Aaron Patterson
RubyKaigi 2025: Class New, A New Approach
tenderlove
0
57
RubyKaigi Dev Meeting 2025
tenderlove
1
3k
Speeding up Instance Variables in Ruby 3.3
tenderlove
2
420
[Feature #20425] Speeding up delegate methods
tenderlove
3
270
RailsConf 2023
tenderlove
30
1.1k
Don't @ Me! Faster Instance Variables with Object Shapes
tenderlove
1
460
RailsConf 2022 Keynote
tenderlove
2
560
Some Assembly Required
tenderlove
1
570
HexDevs 2021
tenderlove
1
460
Other Decks in Technology
See All in Technology
5min GuardDuty Extended Threat Detection EKS
takakuni
0
120
急成長を支える基盤作り〜地道な改善からコツコツと〜 #cre_meetup
stefafafan
0
120
LinkX_GitHubを基点にした_AI時代のプロジェクトマネジメント.pdf
iotcomjpadmin
0
170
AWS アーキテクチャ作図入門/aws-architecture-diagram-101
ma2shita
29
10k
Liquid Glass革新とSwiftUI/UIKit進化
fumiyasac0921
0
190
【TiDB GAME DAY 2025】Shadowverse: Worlds Beyond にみる TiDB 活用術
cygames
0
1k
米国国防総省のDevSecOpsライフサイクルをAWSのセキュリティサービスとOSSで実現
syoshie
2
1k
AIの最新技術&テーマをつまんで紹介&フリートークするシリーズ #1 量子機械学習の入門
tkhresk
0
130
登壇ネタの見つけ方 / How to find talk topics
pinkumohikan
3
350
Observability в PHP без боли. Олег Мифле, тимлид Altenar
lamodatech
0
330
OpenHands🤲にContributeしてみた
kotauchisunsun
1
420
実践! AIエージェント導入記
1mono2prod
0
160
Featured
See All Featured
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.5k
A Tale of Four Properties
chriscoyier
160
23k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
The Cost Of JavaScript in 2023
addyosmani
51
8.4k
YesSQL, Process and Tooling at Scale
rocio
173
14k
Side Projects
sachag
455
42k
Navigating Team Friction
lara
187
15k
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.6k
KATA
mclloyd
29
14k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
22k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Site-Speed That Sticks
csswizardry
10
660
Transcript
None
͜Μʹͪʂ
ຊޠೖྗࢼݧ
Aaron Patterson @tenderlove
GitHub
ko1: ϓϩάϥϛϯάΛ͍ͯͯ͠ʮ͓͓ɺ ੌ͍ίʔυ͕ॻ͚ͨʯʮ͜Εੌ͍ͷ Λ࡞ͬͯ͠·ͬͨʯͷΑ͏ͳܦݧͳͲ
Me: ʮੌ͍ίʔυʯ ͍͍ͬͯͬͨԿͩΖ͏
None
;ͨͭͷҙຯ ڪΖ͍͠ / ා͍ ૉΒ͍͠ / ྑ͍
ೋͭͷτϐοΫ ڪΖ͍͠ / ා͍: PHP ૉΒ͍͠ / ྑ͍: Computer Vision
ൿີ
ੌ͍ίʔυ ૉΒ͍͠ / ྑ͍
ίϯϐϡʔλ Ϗδϣϯ
ΨϥΫλ͕ ͍ͬͺ͍
Magic The Gathering (MtG)ͱ
Collectible Card Game
ࢲͷ (Χʔυͷத) • Too many cards • Don’t know what
they do • Are they worth any money? • Plus many more!
ίϯϐϡʔλʔʹ߹͏ Έ͍ͨ Seems like a job for computers!
ࢲͷղܾ
ਓೳ Χϝϥ ೣ! Ruby!
High Level Process
ࣸਅΛࡱΔ ΧʔυΛൈ͚Δ ΧʔυΛ֬ೝ͢Δ σʔλΛอଘ͢Δ
Χʔυͷೝࣝ
श ͬͨ ਪଌ ϓϩϯϓτ ڭ͑Δ ίʔύε
श ͬͨ ਪଌ ϓϩϯϓτ ڭ͑Δ ίʔύ ε
ਓೳ
σʔλɹϞσϧ
Χʔυͷใ
ࣸਅ ໊લ ਓؾ ηοτ
image belongs_to(:card) card has_one(:image)
None
image belongs_to(:card) card has_many(:images)
None
image habtm(:cards) card habmt(:image)
શσʔλϞσϧ Cards Images Hashes habtm has_many
ίʔύεͷੜ
Executor Pool class ThreadExecutor def initialize size @queue = Queue.new
@size = size @pool = size.times.map { |i| Thread.new { while job = @queue.pop; job.run end } } end def execute job = Proc.new promise = Promise.new job @queue << promise promise end def shutdown @size.times { @queue << nil } @pool.each(&:join) end end
Queue up work promise = @executor.execute do @http_pool.with_connection do |conn|
uri = URI 'http://gatherer.wizards.com/Pages/Default.aspx' response = conn.request uri # save the response end end # some time later promise.value
Me Wizards
1.6GB
http://mtgjson.com/
ॻ͘લʹ άʔάϧͨ͠ํ͕͍͍
Χʔυͷೝࣝ
֮తϋογϡ libphash (gem install phasion)
11998341215223291070 12079686925145871551 Reference Scanned
ϋϛϯάڑ require 'phashion' left = Phashion.image_hash_for "a.jpg" right = Phashion.image_hash_for
"b.jpg" p Phashion.hamming_distance left, right # => 8
5622372658725034411 12079686925145871551 Reference Scanned
ϋϛϯάڑ require 'phashion' left = Phashion.image_hash_for "c.jpg" right = Phashion.image_hash_for
"b.jpg" p Phashion.hamming_distance left, right # => 28
ϋογϡΛՃ͢Δͱ ͕ࣝ૿͑Δ
ϋʔυΣΞ
None
None
None
ιϑτΣΞ
OpenCV https://github.com/ruby-opencv/ruby-opencv
ࡱͬͨࣸਅ
None
ཉ͍͠Πϝʔδ
None
Χʔυͷൈ͖ํ
؆୯ͳ8ஈ֊͚ͩ!* * ؆୯͡Όͳ͍ɺଟ
None
લॲཧ
άϨʔεέʔϧ gray = OpenCV.BGR2GRAY img
None
Τοδݕग़ canny_img = gray.canny @thresh, @thresh http://en.wikipedia.org/wiki/Canny_edge_detector
None
ྠֲΛݟ͚ͭΔ contours = [] contour_node = processed.find_contours( :mode => OpenCV::CV_RETR_TREE,
:method => OpenCV::CV_CHAIN_APPROX_SIMPLE) while contour_node unless contour_node.hole? contours << contour_node end contour_node = contour_node.h_next end
ྠֲ ݀
None
Ұ൪େ͖ͳྠֲ max = contours.max_by { |c| c.contour_area }
None
ଟ֯ܗΛݟ͚ͭΔ approx = max.approx_poly(:method => :dp, :recursive => true, :accuracy
=> 0.02 * peri) x = approx.convex_hull2.to_a clockwise_points = clockwise x.reverse
None
ಁࢹมͷߦྻ to = [ OpenCV::CvPoint2D32f.new(0, 0), OpenCV::CvPoint2D32f.new(width, 0), OpenCV::CvPoint2D32f.new(width, height),
OpenCV::CvPoint2D32f.new(0, height), ] from = polygon_points transform = OpenCV::CvMat.get_perspective_transform(from, to)
ΠϝʔδΛม͢Δ new_img = img.warp_perspective transform
None
ڥք࠲ඪΛઃఆ͢Δ new_img.set_roi OpenCV::CvRect.new(0, 0, width, height)
None
It’s Just That Easy!
ϢʔβʔΠϯλʔϑΣΠε ΧϝϥͰ ࡱͬͨ Πϝʔδ ਪଌ #1 ਪଌ #2 ਪଌ #3
None
Կ͕͋Δʁ Card.joins(:images) .where('images.type' => 'UserImage') .group('cards.name') .count
Ͳͷ͙Β͍ྑ͍ʁ Card.joins(:images) # best .where('images.type' => 'UserImage') .order('rating desc').first Card.joins(:images)
# worst .where('images.type' => 'UserImage') .order('rating asc').first
࠷ߴ:
࠷:
ϓϩδΣΫτͷ
যͷ࣌ؒ
None
ࣦഊͷ࣌
None
ֆࣅͯΔ
None
अຐೣ
None
ར ઃఆ؆୯ ඞཁϋʔυΣΞ͋·Γͳ͍ ͍҆ ΩϟϦϒϨʔτ͠ͳ͍
ܽ ෳࡶͳιϑτΣΞ ࿑ಇ ֬ೝͷ͞
ࠓޙͷ׆ಈ
ࣗಈԽ
ੌ͍ίʔυ ڪΖ͍͠ / ා͍
PHP + Ruby
Phuby (ϑʔϏΟ) https://github.com/tenderlove/phuby એ
Examples
PHPͷ ΦϒδΣΫτΛ͏
ࣈ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$v = strlen('PHP
INSIDE OF RUBY');" puts runtime['v'] # => 18 end
จࣈྻ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$name = 'Aaron';"
puts runtime['name'] # => Aaron end
ྻ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$cars = array('Toyota',
'Honda', 'BMW');" p runtime['cars'][0] # => Toyota p runtime['cars'][1] # => Honda p runtime['cars'][2] # => BMW end
࿈ྻ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$e = array('foo'
=> 'bar', 'bar' => 'baz');" p runtime['e']['foo'] # => 'bar' p runtime['e']['bar'] # => 'baz' end
Rubyͷ ΦϒδΣΫτΛ͏
Objects require 'phuby' class RubyKaigi def where puts "౦ژ" end
end Phuby::Runtime.php do |runtime| runtime['kaigi'] = RubyKaigi.new runtime.eval("$kaigi->where();") # => ౦ژ end
ͳͥʁ
͍͍͔Β
scientists were so preoccupied with whether or not they could
that they didn't stop to think if they should.
ϓϩάϥϜͷମܕ
Runtime Proxy Object Map Ruby Object Proxy PHP Object Proxy
Wrapper Access PHP Objects Ruby C PHP Object Map Ruby
Proxy PHP Runtime Object
Wrapper Access Ruby Objects Ruby C PHP Object Map Ruby
Proxy PHP Runtime Object
ϓϩδΣΫτͷ
PHPΛ ίϯύΠϧ͢Δ
GC
άϩʔόϧͷม
require 'phuby' require 'openssl' p OpenSSL::Cipher.ciphers # => ["AES-128-CBC",
"AES-128-CBC-HMAC-SHA1", ... ] Phuby::Runtime.php do |runtime| runtime.eval("$hi = 'Hello World';") end p OpenSSL::Cipher.ciphers # => []
Solution: fork require 'phuby' require 'openssl' p OpenSSL::Cipher.ciphers # =>
["AES-128-CBC", "AES-128-CBC-HMAC-SHA1", ... ] Process.waitpid fork { Phuby::Runtime.php do |runtime| runtime.eval("$hi = 'Hello World';") end } p OpenSSL::Cipher.ciphers # => ["AES-128-CBC", "AES-128-CBC-HMAC-SHA1", ... ]
Rails Support
PHP templates
None
Πϯελϯεม
None
ActiveRecord͑·͢
None
How much would you pay for this?
200ԁ?
250ԁ?
https://github.com/ tenderlove/phuby FREE!
ൿີͷτϐοΫ
ko1 said this is a tech conference, so you don’t
have to tell any jokes
So I won’t tell any jokes.
ੌ͍ίʔυ How does it work?
Homeopathic Optimizations
Homeopathy ͱʁ
رऍɻ
͗͢Δʂ
None
None
Modern advocates of homeopathy have proposed a concept of "water
memory", according to which water "remembers" the substances mixed in
ਫ هԱग़དྷ·͢
ۭന هԱ͢Δࣄ͕Ͱ͖Δʁ
YES!
σϞͷ࣌ؒ!
None
Ͳ͏ͬͯ ಈ͍ͯΔʁ
VM هԱ͢Δ
ͦΕۭന͡Όͳ ͯ͘ɺهԱͩɻ
ଞͷಛ
None
ར
ߴԽ
"No code is faster than no code"
رऍ͞ΕΕ͞ΕΔ΄Ͳ ϓϩάϥϜΑΓ͘ͳ Δ
ҡ࣋
ίʔυͳ͍͔Β
THANK YOU!!!
࣭ʁ