Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Qiita Night PHP 2023
Search
ふわせぐ
January 26, 2023
Programming
15k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Qiita Night PHP 2023
登壇資料です
ふわせぐ
January 26, 2023
More Decks by ふわせぐ
See All by ふわせぐ
php-conference-nagoya-2025
fuwasegu
0
570
object-oriented-conference-2024
fuwasegu
14
5.8k
proud of my organization LT
fuwasegu
1
500
php conference okinawa 2022
fuwasegu
0
2.1k
QiitaConference2022
fuwasegu
1
1.5k
sleepagotchi
fuwasegu
2
2.7k
何の画像か当てちゃるBot紹介/image_guess_bot
fuwasegu
0
240
新卒 Laravel 初心者が成長していく中で 感じたコレジャナイ感/PHPerKaigi 2022
fuwasegu
11
16k
入社初日に社内サービスを全部一人で引き継いだ新卒フルサイクルエンジニアの話
fuwasegu
4
7k
Other Decks in Programming
See All in Programming
新卒PdEのリアル
ryu1013
1
480
How I Stole PSI from Android Studio - DroidKaigi2026
worker8
0
110
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
660
週末にAI-DLCを本気で回したら$1,600溶けた
hbashimizu
0
130
App Intentsのビルドプロセスを支える技術
kntkymt
0
220
[DroidKaigi 2026] Bring your own phones to Gradle Managed Devices
f2lk
0
110
Swift愛好会と私(ウホーイ) / Swift Fan Club and Uhooi
uhooi
0
150
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
56
37k
RSSとCodexを使ってX投稿自動化してみた
ochtum
0
110
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
1.1k
AIとGame Jamで、ゲームを完成させた話
takahirosaeki
0
120
【DroidKaigi 2026】「アクセシビリティを利用するとき、 アクセシビリティもまたこちらを利用している」 〜マルウェアによる攻撃と防衛について〜
halunoyo
0
440
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.3k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
410
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
57k
How STYLIGHT went responsive
nonsquared
100
6.3k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Ruling the World: When Life Gets Gamed
codingconduct
0
330
Deep Space Network (abreviated)
tonyrice
0
300
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
The Language of Interfaces
destraynor
162
27k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
320
RailsConf 2023
tenderlove
30
1.5k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
210
Transcript
෮ॲཧͱ JUFSBCMFͰ༇շͳؒͨͪ Hirosugu Takeshita @fuwasegu
• 竹下 拓秀 / ふわせぐ (@fuwasegu) • 株式会社ゆめみ / 21卒
– コーポレートエンジニア • PHP / Laravel がメイン – Svelte(JS / TS),Rust Go 勉強中 • 長崎県出身 / 愛知県在住 • !(3 歳)の父 2 自己紹介 Qiita Night 〜PHP〜
宣伝 3 Qiita Night 〜PHP〜 • mpyw さんと二人で Laravel の
ソースコードを読む会 • 隔週で YouTube Live で配信中 • バックナンバー • Model の with • Model の scope • SoftDelete • サービスコンテナ • ルートモデルバインディング • ExceptionHandler 次回: 2023-01-30 14:00:00
• PHP での反復処理について • Generator の紹介 4 今日話すこと Qiita Night
〜PHP〜
5 7 分しかないのでめっちゃ突っ走ります (後日 Qiita に記事出すので詳しくはそちらで) Qiita Night 〜PHP〜
反復処理(Iteration)ってどんなもの? Qiita Night 〜PHP〜 6 反復可能な値の各要素に対して,同じ処理を順番に行うこと
• オブジェクト • iterable 型 7 PHP で反復可能な値になりうるもの Qiita Night
〜PHP〜
• オブジェクト 8 PHP で反復可能な値になりうるもの Qiita Night 〜PHP〜 アクセス権限があるプロパティは, foreach
で取り出せる (private なものは取り出せない)
• iterable 型 9 PHP で反復可能な値になりうるもの Qiita Night 〜PHP〜 今日の本題はこっち
• iterable = (Traversable | array) – 型のエイリアス – PHP7.1
〜 PHP8.0 では疑似型 – それ以前は未定義 • foreach で反復処理ができるもの • iterator_to_array() に渡すと array になるもの – iterator_to_array() の引数 Traversable | array になったのは PHP8.2 から – それまでは Traversable のみだった 10 iterable とは Qiita Night 〜PHP〜
11 Qiita Night 〜PHP〜 iterable array Traversable
12 Qiita Night 〜PHP〜 iterable array Traversable IteratorAggregate Iterator Generator
extends extends extends implements
13 Qiita Night 〜PHP〜 iterable IteratorAggregate Iterator Generator extends extends
extends implements 時間がないので説明は割愛
Iterator とは • 反復処理中の状態を持つオブジェクト自身を 定義するinterface – 現在の要素を取得 – 現在のキーを取得 –
次の要素に進む – 最初の要素に巻き戻し – 現在位置が有効かどうか 取得 Qiita Night 〜PHP〜 14
IteratorAggregate とは • Iterator(Traversable) を作る interface • 自分自身が要素を持ったり状態を管理するわけ ではない Qiita
Night 〜PHP〜 15 • getIterator() は新しいイテレータ を返す • foreach に IteratorAggregate を渡 すと勝手に getIterator() が呼ばれ る ポイント
Generator とは • イテレータが簡単に作れるやつ – 本来 Iterator を自前で作る場合,インタフェースに定 義されたメソッドをそれぞれ実装する必要がある –
Generator は yield するだけで良い • 遅延評価される(= 省メモリ) – 値(演算結果)が必要になったときに初めて評価 されるということ Qiita Night 〜PHP〜 16
17 ジェネレーター構文の例 Qiita Night 〜PHP〜
18 ジェネレーター構文の例 Qiita Night 〜PHP〜 まだ何が嬉しいか分からん!
19 もうちょっと 具体的なユースケースを考えます Qiita Night 〜PHP〜
仮想の要件 • 大容量の CSV ファイルを読み込む – ID,姓,名,生年月日,郵便番号,電話番号,メールアドレ ス,性別 • フィルターしてデータを抜き出す
– 名字が山田 – 二十歳以上 – 男 – 頭から 3 件取得する Qiita Night 〜PHP〜 20
愚直に実装してみる(方針) • 一気には読み込めないので一行ずつ読む – fopen() して fgetcsv() しながらループ • ループの中で
条件に合致しなかったら読み 飛ばす • カウンタを作っておいてインクリメントしていく – 必要数集まったら break Qiita Night 〜PHP〜 21
22 Qiita Night 〜PHP〜 条件の数だけ if を並べる 1個の if にまとめる
愚直に実装してみる(実装) 文字が小さいのは許して
23 Qiita Night 〜PHP〜 愚直に実装してみる(実装)
24 メソッドに分割してみる Qiita Night 〜PHP〜 年齢でフィルター 名前でフィルター 性別でフィルター 指定要素数取り出し
• 一見見通しが良くなったが,前もって CSV を全部読み込む必要があり激重 • 毎回 foreach で全探索するので激重 25 分割したメソッドで組み立て
Qiita Night 〜PHP〜 CSV が大きいとメモリが食いつぶされます
26 Generator を使って書き直す Qiita Night 〜PHP〜 年齢でフィルター 性別でフィルター 名前でフィルター 指定要素数取り出し
CSV 読み込み
27 Generator を使って書き直す Qiita Night 〜PHP〜 今回は Generator 関数を用いましたが,IteratorAggregate を
使ってクラスごとに分割する方法もあります (Qiita で解説します!)
• さっきと見た目は変わらない • 全て Generator なので CSV を一気に読み 込む必要も無くなった 28
分割したメソッドで組み立て Qiita Night 〜PHP〜 CSV がどれだけ大きくても動作します
• Generator を使わない場合 – Fatal error: Allowed memory size of
134217728 bytes exhausted (tried to allocate 20480 bytes) • Generator を使った場合 – 2936 バイトで正常に終了 29 実験 Qiita Night 〜PHP〜 • 100 万行の CSV(77.2 MB)を入力 • CSV の読み込み 〜 フィルターにかかる使用メモリを計測 結果
• Generator は yield が呼ばれるたびに値を生成する – Generator でない場合要素分のメモリが必要 – Generator
が生成した値は消費されるので古いものは破棄される – つまり巻き戻せない(単一方向の Iterator) • Generator は値が必要になったときに初めて評価される – 並列で並べた時,Generator でない場合毎回全部ループして都度 全要素評価する – Generator の場合,一行読み込むたびに次の処理に移れる 30 なぜ Generator は省メモリなのか Qiita Night 〜PHP〜 メモリの使用量が要素数に比例しないので,無限長のリストを扱える
31 実際の処理を見てみよう Qiita Night 〜PHP〜 6, 2, 10, 9, 3,
12 読み取りたいデータ <?php $data = read_data(); // 5 以上の整数に絞る $result = filter_1($data); // 偶数に絞る $result = filter_2($result); // 頭から 2 つだけとる $result = take($result, 2); foreach ($result as $item) { echo $item; } 擬似コード
32 Generator を使わない場合 Qiita Night 〜PHP〜 全部読み込み 全探索で絞り込み 全探索で絞り込み 早期リターン
出力 <?php $data = read_data(); // 5 以上の整数に絞る $result = filter_1($data); // 偶数に絞る $result = filter_2($result); // 頭から 2 つだけとる $result = take($result, 2); foreach ($result as $item) { echo $item; }
33 Generator を使わない場合 Qiita Night 〜PHP〜 6 2 10 9
3 12 read_data 1 2 3 4 5 6 filter_1 7 8 9 10 11 12 filter_2 13 14 15 16 take 17 18 foreach 19 20 データ 処理 黒の数字は読み取り順 処理が軸になる
34 Generator を使う場合 Qiita Night 〜PHP〜 1 要素目 2 要素目
3 要素目 <?php $data = read_data(); // 5 以上の整数に絞る $result = filter_1($data); // 偶数に絞る $result = filter_2($result); // 頭から 2 つだけとる $result = take($result, 2); foreach ($result as $item) { echo $item; }
35 Generator を使う場合 Qiita Night 〜PHP〜 6 2 10 9
3 12 read_data 1 6 8 filter_1 2 7 9 filter_2 3 10 take 4 11 foreach 5 12 データ 処理 黒の数字は読み取り順 値が軸になる
• Generator を使わない場合 – 全てのデータを読み込んだ – メソッドは呼び出し時に実行された – 毎回全要素を参照した •
take の早期リターンは例外 • Generator を使った場合 – 全てのデータは読み込まなかった – メソッドは呼び出し時に実行されなかった • 要素ごとに遅延実行された – 演算対象の要素のみ参照した 36 結果 Qiita Night 〜PHP〜 <?php $data = read_data(); // 5 以上の整数に絞る $result = filter_1($data); // 偶数に絞る $result = filter_2($result); // 頭から 2 つだけとる $result = take($result, 2); foreach ($result as $item) { echo $item; }
37 Qiita Night 〜PHP〜 Generator はいいぞ!