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
Rails JSON APIとサービス高速化 / JSON Serializer 2020
Search
lni_T
July 30, 2020
Programming
5.6k
9
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Rails JSON APIとサービス高速化 / JSON Serializer 2020
「リードエンジニアから学ぶMedPeerのプロダクト開発」
https://medpeer.connpass.com/event/181835/
lni_T
July 30, 2020
More Decks by lni_T
See All by lni_T
ruby.wasmで多人数リアルタイム通信ゲームを作ろう
lnit
3
1k
Rails産でないDBを Railsに引っ越すHACK - Omotesando.rb #110
lnit
2
290
ruby.wasmとWebSocketで遊ぼう!
lnit
0
270
ActiveRecordの力でDBのメタデータを迅速に解析する
lnit
6
3.2k
ruby.wasm × Service Workerでサーバーのいらないモックサーバーを作る
lnit
0
460
Railsアプリの仕様書を一瞬で作りたい話 - Omotesando.rb #99
lnit
1
440
ruby.wasm 最前線 2024 - wasmでMockServerをつくる #rubykaigi
lnit
2
4.4k
Turbolinksアレルギー患者に捧げるTurbo & Stimulusでの時短実装術 / Kaigi on Rails 2023
lnit
4
6.3k
ruby.wasmでブラウザを酷使してみよう / 2023-MatsueRubyKaigi
lnit
0
1.9k
Other Decks in Programming
See All in Programming
変わらないものが、変わるものを決める — 意図駆動開発 × イベントソーシング × イミュータブル | What Doesn't Change Decides What Can — IDD × Event Sourcing × Immutability
tomohisa
0
1.1k
php-fpmのプロセスが枯渇した日-調査・対処・そして本当にやるべきだったこと-
shibuchaaaan
0
200
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
800
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
1
3.4k
言葉の格闘技のススメ~紙とペンと言葉から始める、キャリアの描き方~
progresscicada
1
110
【やさしく解説 設計編・中級 #6】良いアーキテクチャとは ~ 一本の登り道の、行き先 ~
panda728
PRO
0
200
FDEが実現するAI駆動経営の現在地
gonta
2
250
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
200
Japan Community Day at Kubecon + CloudNativeCon Japan 2026: Learning Container Privilege Control by Building My Own Low-Level Container Runtime
ternbusty
1
120
その節約、円になってますか?
isamumumu
1
670
20260722_microCMSで考える、AI時代のコンテンツ運用設計
yosh1
0
270
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
300
Featured
See All Featured
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.5k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.1k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
3
1.1k
Chasing Engaging Ingredients in Design
codingconduct
0
260
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
370
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
430
RailsConf 2023
tenderlove
30
1.5k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
790
Transcript
+40/"1*ͱ αʔϏεߴԽ
ࣗݾհ w 5XJUUFS!MOJ@5 (JUIVC!MOJU w .FE1FFS&OHJOFFS ʙ w ͖ͳ3BJMTͷϝιου
QSFTFODF w ݏ͍ͳ3BJMTͷϝιου BDDFQUT@OFTUFE@BUUSJCVUFT@GPS
ΫϦχοΫ։ۀࢧԉ ϓϥοτϑΥʔϜ
݅୳͠ ϊϋऩू
ͭͬͨ͘ػೳ (PPHMF.BQ্Ͱ ݅୳͠ ڝ߹ͷఁ ױऀ༧ଌ ͕ͻͱͰ͔Δͭ
ϦϦʔεޙʹ͕
ͱ͍ͯ
ද͕͍ࣔ ݕࡧ͔ͯ͠Β݅Λදࣔ͢Δ·Ͱʜ ඵʙඵ
݅୳͠αʔϏε ͳͷʹ ୳͢ͷ͕͍ʂ
+40/"1*Λ͘ʂ ˢຊͷςʔϚ
ݪҼʁ
བྷతࢥߟ ฦ٫͢Δ݅ʹൺྫͯ͠ύϑΥʔϚϯεѱԽ
བྷతࢥߟ ฦ٫͢Δ݅ʹൺྫͯ͠ύϑΥʔϚϯεѱԽ ύϑΥʔϚϯεͱ͍͑%# Ͱ ͑ ͑
བྷతࢥߟ %#पΓͷΑ͋͘ΔରԠΛͬͯΒͬͨ JOEFYுΔ / ͳ͘͢
ղܾʂ ΊͰͨ͠ʁ
ղܾ͠ͳ͔ͬͨ ݅"1* վળલ վળޙ
ͱ͍ͯˠ͍ ඵˠඵ
ϘτϧωοΫ୳͠ %#͡Όͳ͍ͳΒʜ Completed 200 OK in 2199ms (Views: 2127.1ms
| ActiveRecord: 51.2ms) Completed 200 OK in 2300ms (Views: 2200.7ms | ActiveRecord: 67.0ms)
ϘτϧωοΫ୳͠ 7JFXT͕͍ʂ KTPOͷϨϯμϦϯά෦ʁ (Views: 2127.1ms | ActiveRecord: 51.2ms)
(Views: 2200.7ms | ActiveRecord: 67.0ms)
+40/γϦΞϥΠζ ͳΜͱ͔͢Δ
+40/γϦΞϥΠζ ʮ"DUJWF.PEFM4FSJBMJ[FSTʯΛར༻͍ͯͨ͠ ฮHFNͰ͍͍͢ ύϑΥʔϚϯε໘ͰଞHFNͱൺֱ͞Ε͕ͪ KCVJMEFSΑΓ͍ͷ͕ͩʜ
Γ͑ʂ
ͦͦ +40/γϦΞϥΠβ Կ͍͍͑ʁ
ௐࠪ
ଟछଟ༷ͳબࢶ
None
+40/γϦΞϥΠβ ઓࠃ࣌
ൺֱ
ൺֱ ൺֱର KCVJMEFS "DUJWF.PEFM4FSJBMJ[FST ".4
GBTU@KTPOBQJ KC
KCVJMEFS # app/views/messages/show.json.jbuilder json.content format_content(@message.content) json.(@message, :created_at, :updated_at) json.author do
json.name @message.creator.name.familiar json.email_address @message.creator.email_address_with_name json.url url_for(@message.creator, format: :json) end json.comments @message.comments, :content, :created_at
KCVJMEFS (PPE 3BJMTσϑΥϧτࡌ ৽نϝϯόͷֶशίετ ϝϯς͞Ε͍ͯΔ 3BJMTίΞνʔϜ
ҙͷεΩʔϚͰฦ٫Ͱ͖Δ #BE ʜ ಠಛͳه๏͕ͳ͡·ͳ͍ਓଟ͍ 0UIFS (*U)VCελʔL
".4 class PostSerializer < ActiveModel::Serializer attributes :title, :body has_many :comments
has_one :author end class CommentSerializer < ActiveModel::Serializer attributes :name, :body belongs_to :post end
".4 (PPE 4FSJBMJ[FSΫϥεͷ࣮ςετ͕Մೳ ҙͷεΩʔϚͰฦ٫Ͱ͖Δ #BE
ϝϯςφϯε͞Ε͍ͯͳ͍ 0UIFS KCVJMEFSΑΓ͍͕ଞHFNͱൺֱ͢Δͱ͍ (JU)VCελʔL
GBTU@KTPOBQJ class MovieSerializer include FastJsonapi::ObjectSerializer attributes :name, :year has_many :actors
belongs_to :owner, record_type: :user belongs_to :movie_type end json_string = MovieSerializer.new(movie).serialized_json
GBTU@KTPOBQJ (PPE 4FSJBMJ[FSΫϥεͷ࣮ςετ͕Մೳ ߴʂ #BE
ϝϯςφϯε͞Ε͍ͯͳ͍ ˞ຊՈ͔Β'PSL͞ΕͨϦϙδτϦͰϝϯς͞ΕͯΔ 0UIFS εΩʔϚ͕+40/"1*ʹݶఆ͞ΕΔ (JU)VCελʔL
GBTU@KTPOBQJ +40/"1* +40/ߏͷن UZQF JEඞਢ ΞιγΤʔγϣϯ
SFMBUJPOTIJQT JODMVEFE Ͱදݱ͢Δ { "data": [{ "type": "articles", "id": "1", "attributes": { "title": "JSON:API paints my bikeshed!" }, "relationships": { "author": { "data": { "type": "people", "id": "9" } }, }, }], "included": [{ "type": "people", "id": "9", "attributes": { "firstName": "Dan", "lastName": "Gebhardt", }, }] }
KC # app/views/messages/show.json.jb json = { content: format_content(@message.content), created_at: @message.created_at,
updated_at: @message.updated_at, author: { name: @message.creator.name.familiar, email_address: @message.creator.email_address_with_name, url: url_for(@message.creator, format: :json) } } json[:comments] = @message.comments.map do |comment| { content: comment.content, created_at: comment.created_at } end json
KC (PPE KCVJMEFSΑΓૉʹ3VCZͬΆ͘ॻ͚Δ ߴʂ ҙͷεΩʔϚͰฦ٫Ͱ͖Δ
ϝϯςφϯε͞Ε͍ͯΔ #BE ʮ4FSJBMJ[FSͷςετॻ͖͍ͨʂʯਓ߹Θͳ͍͔ 3FRVFTU4QFD4ZTUFN4QFDͰॻ͘͜ͱʹͳΔ 0UIFS (JU)VCελʔ
KCVJMEFS ".4 GBTU@ KTPOBQJ KC º ˓ ˕ ˕
εΩʔϚ ࣗ༝ ˓ ˓ ˚ ˓ ςετ ͢͠͞ ˚ ˓ ˓ ˚ HFN ϝϯς ˕ º ˚ ˓ ˞ݸਓͷײͰ͢
ɾТɾʆ Ͳ͏͠Α͏
ࠓճ͕ͳͷͰ ϕϯνϚʔΫ ΈΜͳ͍͖ͩ͢ CFODINBSLJQT
CFODINBSLJQT def benchmark Benchmark.ips do |x| x.report('ams') do render_to_string json:
ams_tenants, serializer: Ams::TenantSerializer end x.report('fast_jsonapi') do json = FastJsonapi::TenantSerializer.new(tenants).serialized_json render_to_string json: json end x.report('jb') do render_to_string 'index' end x.compare! end end
CFODINBSLJQT ".4ˠGBTU@KTPOBQJKCʹΓ͑Δ͚ͩͰʜ ഒݟࠐΈʂ˞EFWFMPQNFOUڥଌఆ Αͦ͞͏ʂ Comparison: jb: 2.0
i/s fast_jsonapi: 1.8 i/s - 1.10x (± 0.00) slower ams: 1.2 i/s - 1.64x (± 0.00) slower
Γ͑ Ұ෦"1*ͷʮKCʯͷΓ͑Λબ બఆཧ༝ ߴ ҙͷεΩʔϚͰฦ٫Ͱ͖Δ
+4ଆ࣮ࡁͷͨΊεΩʔϚมߋΓͨ͘ͳ͍
ຊ൪ϦϦʔε݁Ռ
TҎ౸ୡʂ "status":200,"duration":449.96,"view":299.48,"db":97.36
TҎ౸ୡʂ ݅"1* վળલ վળͦͷ վળͦͷ
ΊͰͨ͠
·ͱΊ
֤HFNͷॴײ KCVJMEFS ඪ४ࡌ͕ڧΈ ֶशίετɺϝϯςφϯεܧଓੑ ։ൃίετॏࢹʹ͕ແ͍߹ʹ͓͢͢Ί
ࠓޙ৽ͨͳΓ͑ઌ͕ݟ͔ͭΔʜ͔ʁ "DUJWF.PEFM4FSJBMJ[FST ͳΜ͔ͩΜ͍͍ͩ͢ ϝϯς͞Εͯͳ͍ͷ͕ਏ͍ʜ ࠓ͍͑ͯΔਓɺ ٸ͗Γ͑ͳͯ͘Αͦ͞͏
֤HFNͷॴײ GBTU@KTPOBQJ ॏࢹͷ߹ʹ͓͢͢Ί +40/"1*ͷ੍Λڐ༰Ͱ͖ΔͳΒ͍͍͢ ˞ύονͰಈ࡞Λվม͢Δཪٕ
KC ॏࢹͷ߹ʹ͓͢͢Ί 7JFXʹ௨ৗͷSVCZͬΆ͘ॻ͘ه๏͕߹͍͍͑͢
·ͱΊ ϘτϧωοΫͭͱݶΒͳ͍ͷͰࠜؾΑ͘վળ͠Α͏ ϓϩμΫτͷɺϏδωεͷঢ়گΛؑΈͯ ͦͷ࣌ʑʹ߹ٕͬͨज़બఆΛ͠Α͏ ͲͷΞϓϦʹ߹͏+40/γϦΞϥΠβͷܾఆ൛ ݱࡏܾΊΒΕͳͦ͞͏
KCVJMEFS ".4 GBTU@ KTPOBQJ KC º ˓ ˕ ˕
εΩʔϚ ࣗ༝ ˓ ˓ ˚ ˓ ςετ ͢͠͞ ˚ ˓ ˓ ˚ HFN ϝϯςφ ˕ º ˚ ˓