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
Swift Macroでメソッドの実行時間を計測できるようにしてみた
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Ryu-nakayama
October 25, 2024
Programming
240
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Swift Macroでメソッドの実行時間を計測できるようにしてみた
2024/10/25 mobile.stmn #8の登壇資料です
Ryu-nakayama
October 25, 2024
More Decks by Ryu-nakayama
See All by Ryu-nakayama
iOS機能開発のAI環境と起きた変化
ryunakayama
0
230
日本だけで解禁されているアプリ起動の方法
ryunakayama
0
420
iOSアプリでフロントエンドと仲良くする
ryunakayama
0
150
「ジェン文字」使ってますか?
ryunakayama
0
78
Health Kit × Foundation Models でAIコーチを作ってみた
ryunakayama
0
360
iOSの画面の状態のアレコレを調査してみた
ryunakayama
0
100
作文ツール(Writing Tools)をアプリから制御する
ryunakayama
0
64
iOSアプリで測る!名古屋駅までの 方向と距離
ryunakayama
0
310
「ジェン文字」をアプリ内で使ってみよう
ryunakayama
0
200
Other Decks in Programming
See All in Programming
1B+ /day規模のログを管理する技術
broadleaf
0
130
symfony/aiとlaravel/boost
77web
0
120
LaravelLive Japan の裏方のすべて — 第188回 PHP勉強会@東京 (2026-06-24)
suguruooki
2
150
SREは、MCPとSRE Agentをこう使え!
kazumax55
0
150
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
0
2.1k
【やさしく解説 設計編 #1】「ドメイン駆動」と「実装駆動」ってなに? 〜設計の考え方を、たとえ話で学ぼう〜
panda728
PRO
1
100
エンジニアにデザインハーネスを 〜デザインプロセスを規定するためのハーネス〜 / Design harness from an engineer's perspective
rkaga
2
1.3k
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
17
8.8k
壊れたパーサから始める関数型設計と構成的なパーサ #fp_matsuri
raiga0310
2
190
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.7k
アルゴリズムは何を圧縮しているのか ─ Haskell から育った「圧縮代数」というメンタルモデル
naoya
15
3.2k
Featured
See All Featured
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
230
Prompt Engineering for Job Search
mfonobong
0
370
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
320
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
260
For a Future-Friendly Web
brad_frost
183
10k
4 Signs Your Business is Dying
shpigford
187
22k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
460
Ruling the World: When Life Gets Gamed
codingconduct
0
280
Optimizing for Happiness
mojombo
378
71k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
Transcript
Swift Macroでメソッドの実行時間を 計測できるようにしてみた CP本部 iOSアプリ開発部 中山 龍 2024年10月25日 mobile.stmn #8
自己紹介 中山 龍 (なかやま りゅう) • 株式会社kubell ◦ 新卒2年目のiOSエンジニア(22) ◦
「Chatwork」アプリの開発を担当 • 愛知県在住 ◦ 日曜に引っ越しをし、熱田区民 → 中区民に @ryu_develop
今更ながらSwift Macro (Swift Syntax) で遊んでみたのでその内容を紹介します
注意事項 • 本スライドの内容や登場するコードは趣味で作成しているものであり、業 務で扱っているプログラム・プロダクト・開発環境とは一切関係ありません • 「試しに触ってみた」という趣旨の紹介であり、必ずしもベストプラクティス を紹介しているわけではありません • スライド・GitHubに掲載しているコードも完璧な動作を保証するものでは ありません
01 | Swift Macroとは
Swift Macroとは? - Swiftプログラム内でコンパイル時にコードを自動生成したり、変換したりする ための機能 - Swift5.9以降で導入 - @〜〜〜 や
#〜〜〜といった感じで使用する 参考: Swiftマクロの書き方 - WWDC2023 代表的なものだと - Observation (@Observable) - SwiftUIのプレビュー (#Preview) 強力で便利な機能だが、可読性などの観点から乱用しないように注意が必要!
02 | 実行時間を計測するMacroを書いてみた
完成イメージ 8 @(自作のMacro) 型に対して自作のMacroを付ける 型のメソッドを実行した時に、 実行したメソッド と時間 が表示され る
コードが見づらい部分も多いと思うので... https://github.com/Ryu-nakay/measuri ng-method-execution-time-macro.git コードを中心に説明をすると字が小さくて見づらいことが 想定されるので、文字中心で説明します〜!🙏 コードは必要に応じてGitHubをご覧ください → (スライドはイベント終了後に公開するので、その際に照ら し合わせながら見ていただくでも問題なし) 会場の様子を見ながら、必要そうであればライブコーディング風にお見せします
1. 単体のメソッドを計測可能にする
ルール: メソッドの実行時間の計測 メソッドの 処理開始時の時刻 と 処理終了時の時刻 の差を実行時間とする 11 終了時刻 開始時刻
実行時間 10時 20分 40秒 10時 20分 30秒 10秒 ざっくりとしたイメージ
ルール: メソッドの実行時間の計測 メソッドの 処理開始時の時刻 と 処理終了時の時刻 の差を実行時間とする 12 終了時刻 開始時刻
実行時間 10時 20分 40秒 10時 20分 30秒 10秒 ざっくりとしたイメージ メソッドの開始時刻と終了時刻を取得し、その差を 出力すればよさそう!
ルール: メソッドの実行時間の計測 -作成するMacroのイメージ- 13 展開 @自作Macro @自作Macro (今回、defer文などは考慮していません )
ルール: メソッドの実行時間の計測 -計測に使用する便利な型- 14 計測の事前準備として、MeasureTimeLoggerという型を作りました - 初期化時に時刻でプロパティを初期化 - stop呼び出しで実行時間の計算とprint出力
ルール: メソッドの実行時間の計測 -計測に使用する便利な型- 15 展開 BodyMacro を使ってメソッドの中身を書き換えよう!
2. BodyMacroを実装する
実装 -型の準備- BodyMacroに準拠した型を定義し、expansionメソッドを準備します // 実装
実装 -expansionメソッドの中身- 1. Macroが付与されている対象がメソッド構文であることを確認し、そのメソッドの中身の構文を取得する (できなければ何もイジらずに return) 2. メソッドの中身の構文を 1行ずつ取り出し、その行が return構文だった場合には、その前に
`measureTimeLogger.stop()` をくっつける return構文が存在していなかった場合には、メソッドの中身の構文の末尾に `measureTimeLogger.stop()`をくっつ ける 3. メソッドの中身の先頭に `let measureTimeLogger = MeasureTimeLogger()`をくっつける
実装 -expansionメソッドの中身- 1. Macroが付与されている対象がメソッド構文であることを確認し、そのメソッドの中身の構文を取得する (できなければ何もイジらずに return) 2. メソッドの中身の構文を 1行ずつ取り出し、その行が return構文だった場合には、その前に
`measureTimeLogger.stop()` をくっつける return構文が存在していなかった場合には、メソッドの中身の構文の末尾に `measureTimeLogger.stop()`をくっつ ける 3. メソッドの中身の先頭に `let measureTimeLogger = MeasureTimeLogger()`をくっつける 1. Macroが付与されている対象がメソッド構文であることを確認し、そのメソッドの中身の構文を取得する (できなければ何もイジらずに return) - expansionメソッドの引数 declaration が FunctionDeclSyntax型に変換できるかで判定する - FunctionDeclSyntax.body?.statements がメソッドの中身の構文となる
実装 -expansionメソッドの中身- 1. Macroが付与されている対象がメソッド構文であることを確認し、そのメソッドの中身の構文を取得する (できなければ何もイジらずに return) 2. メソッドの中身の構文を 1行ずつ取り出し、その行が return構文だった場合には、その前に
`measureTimeLogger.stop()` をくっつける return構文が存在していなかった場合には、メソッドの中身の構文の末尾に `measureTimeLogger.stop()`をくっつ ける 3. メソッドの中身の先頭に `let measureTimeLogger = MeasureTimeLogger()`をくっつける - 1.で取得した『メソッドの中身の構文』を 1行ずつ取り出し、その型が ReturnStmtSyntaxかどうか でreturn構文を判定することができる - 元の構文 + 処理終了時の構文となったものが出来上がる 2. メソッドの中身の構文を 1行ずつ取り出し、その行が return構文だった場合には、その前に `measureTimeLogger.stop()` を付け加える return構文が存在していなかった場合には、メソッドの中身の構文の末尾に `measureTimeLogger.stop()`を付け加 える
実装 -expansionメソッドの中身- 1. Macroが付与されている対象がメソッド構文であることを確認し、そのメソッドの中身の構文を取得する (できなければ何もイジらずに return) 2. メソッドの中身の構文を 1行ずつ取り出し、その行が return構文だった場合には、その前に
`measureTimeLogger.stop()` をくっつける return構文が存在していなかった場合には、メソッドの中身の構文の末尾に `measureTimeLogger.stop()`をくっつ ける 3. メソッドの中身の先頭に `let measureTimeLogger = MeasureTimeLogger()`をくっつける 3. メソッドの中身の先頭に `let measureTimeLogger = MeasureTimeLogger()`を付け加える - 2.で作成した『元のメソッドの構文 + メソッド終了時の構文』の先頭にメソッド開始時の構文を付け 加えてreturnする
最終的なBodyMacroの実装 https://github.com/Ryu-nakay/measuri ng-method-execution-time-macro.git
実装 あとは、Macroを使えるようにするために各所に記述を追加し ...
実装 無事に時間計測ができるようになりました!
Macro展開時 ↑ Macroを展開すると計測開始・終了の処理が付け加えられ ていることがわかります
一括でつけたい 無事に計測可能になったものの... 毎回メソッドに付与していくの面倒だなぁ... 一括で型のメソッド全てを計測可能にできないかな?
再掲: 完成イメージ 27 @(自作のMacro) 型に対して自作のMacroを付ける 型のメソッドを実行した時に、 実行したメソッド と時間 が表示され る
こうすればいける? 28 @(自作のMacro) Macroを展開 メソッド単体での計測はできるので、型に対してMacroをつけた時に右のように各 メソッドに @MeasureTimeが付与されるようにすればいいのでは?
3. MemberAttributeMacroを実装する
実装 -最終的なMemberAttributeMacroのコード- さっきと比べるとすごくシンプル!
実装 -最終的なMemberAttributeMacroのコード- expansionを実装 memberがメソッドの 構文であるかを判定 メソッドの構文であるものに対して @MeasureTimeを付与
実装 -最終的なMemberAttributeMacroのコード- expansionを実装 memberがメソッドの 構文であるかを判定 メソッドの構文であるものに対して @MeasureTimeを付与 これだけで完成!
実装 あとは、Macroを使えるようにするために各所に記述を追加し ...
使ってみる 34 Macroを展開 型に @TimeMeasureable を付けることで、その型が持つメソッドに @MeasureTimeを付与できました!
まとめ
まとめ・感想 36 まとめ • メソッド単体で計測可能することができる @MeasureTime を実装した ◦ BodyMacro •
型のメソッドに @MeasureTimeを付与できる @TimeMeasureableを実装した ◦ MemberAttributeMacro 感想 • 「Swift Macro / Swift Syntaxって専門知識がないと難しそう」と食わず嫌いしていたが、実際に 触ってみると動くものを作れるぐらいにはできた • Swift AST Explorer が便利すぎた ◦ Syntaxの深い知識を持ち合わせていなくても構造や型を調べられた • 本当は「Swiftのコードから実行された処理のシーケンス図を出力したい」というモチベーションで 始めたので、今後実現できたらと ...
働くをもっと楽しく、創造的に 37