Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHP 8.3のmbstringの進化を見てください - コントリビューターとしてのかかわり -

PHP 8.3のmbstringの進化を見てください - コントリビューターとしてのかかわり -

https://fortee.jp/phpcon-2023/proposal/f80e2361-e363-4eb4-8754-c4705ee31eb0

スライドのリンク集

6ページ目
https://tekitoh-memdhoi.info/views/864

8ページ目
https://github.com/php/php-src/pull/10048
https://github.com/php/php-src/pull/10099
https://github.com/php/php-src/pull/10107
https://github.com/php/php-src/pull/10178

9ページ目
https://github.com/php/php-src/pull/10211
https://github.com/php/php-src/pull/10230
https://github.com/php/php-src/pull/10264

10ページ目
https://github.com/php/php-src/pull/10313
https://github.com/php/php-src/pull/10384

11ページ目
https://github.com/php/php-src/pull/10313
https://github.com/php/php-src/pull/10384
https://github.com/php/php-src/pull/10409

12ページ目、20ページ目
https://arxiv.org/abs/2010.03090
https://qiita.com/saka1_p/items/9719d71e702aed92a07c
https://github.com/simdjson/simdjson

21ページ目
https://github.com/php/php-src/pull/10436

22ページ目
https://github.com/php/php-src/pull/11076
https://github.com/cyb70289/utf8
https://tekitoh-memdhoi.info/views/872

23ページ目
https://github.com/php/php-src/pull/10452

24ページ目
https://github.com/php/php-src/issues/10853

25ページ目
https://github.com/php/php-src/pull/10488

26ページ目
https://github.com/php/php-src/pull/10373

27ページ目
https://github.com/php/php-src/issues/10651

28ページ目
https://github.com/php/php-src/pull/10828

29ページ目
https://github.com/php/php-src/pull/11161

30ページ目
https://github.com/php/php-src/pull/11213

31ページ目
https://github.com/php/php-src/pull/11259

32ページ目
https://github.com/php/php-src/issues/11567

33ページ目
https://github.com/php/php-src/issues/11587
https://github.com/php/php-src/pull/11622

34ページ目
https://github.com/php/php-src/pull/11742

35ページ目
https://github.com/php/php-src/pull/11742

36ページ目
https://github.com/php/php-src/issues/11878
http://doc.php.net/tutorial/local-setup.php

37ページ目
https://github.com/php/doc-en/pull/2647

38ページ目
https://github.com/php/php-src/pull/12228
https://unicode.org/consortium/staff.html

39ページ目
https://wiki.php.net/rfc/mb_str_pad

PHP Foundation
https://thephp.foundation/

てきめん tekimen

October 08, 2023
Tweet

More Decks by てきめん tekimen

Other Decks in Programming

Transcript

  1. PHP 8.3のmbstring
    の進化を見てください
    - コントリビューターとしてのかかわり -
    PHP 8.3のmbstring
    の進化を見てください

    View Slide

  2. 自己紹介
    てきめん
    ● https://tekitoh-memdhoi.info
    ● X(twitter): @youkidearitai
    ● https://github.com/youkidearit
    ai
    ● サイボウズ株式会社の契約社員
    – コントリビュートしまくったら入
    社した
    ● オレはオレ
    オレ

    View Slide

  3. アジェンダ
    ● PHP 8.3のmbstringをリアルタイムで見てました
    ● GitHubでContributorフラグをもらえました
    ● コントリビュートのお手伝いができるようになりました
    ● php-src上で誰に何をお願いすればいいのかわかっ
    てきました

    View Slide

  4. このスライドで出てくるみなさん
    ● @illuuu1994 Ilija Toviloさん
    – Coreが強い、Dmitry(@dstogov)さんともやり取りしてる印象
    ● @Girgias George Peter Banyardさん
    – Coreからextまで広くコントリビュートしてくれてる、docもメンテしてくれてる
    ● @alexdowad Alex Dowadさん
    – mbstringでお世話になってる
    ● @nielsdos Niels Dosscheさん
    – Coreも強い

    View Slide

  5. このスライドで出てくるみなさん
    ● @youkidearitai てきめんさん
    – 私てきめん、mbstringとか見てる
    ● @pakutoma ぱくとまさん
    – 後に同僚になる、コントリビュートに協力した
    ● @SakiTakamachi さきちさん
    – コントリビュートに協力した
    ● @mumumuさん
    – docのコントリビューター。最近のPHPのドキュメントが早いのはこの方のおかげ

    View Slide

  6. 皆さんは覚えてますか
    ● 非公式 PHP 8.1 mbstringアップグレードガイド
    – https://tekitoh-memdhoi.info/views/864
    – 皆さんのお陰でかなりの反響をいただき、ありがたい
    ● これをAlex Dowadさんに見せたところ、FYA(For Your
    Action)をもらうようになった
    – 2022年の12月から。まだ8.3というバージョン名が付く前
    ● ていうか、世間ではPHP 8.2がリリースされたっていうタイミング

    View Slide

  7. PHP 8.3のmbstringの面倒を見てました
    ● PHP 8.3のmbstringの面倒を見てました
    ● 2022年12月から始まりました
    – 2023年7月のFeature Freezeを見届けました

    View Slide

  8. 何があったかリスト
    ● Major overhaul of mbstring (part 27) #10048
    ● Major overhaul of mbstring (part 28) #10099
    ● Performance optimization for mb_stripos an
    d mitigation for GH-9613 #10107
    ● Allow 'h' and 'k' flags to be combined for mb_
    convert_kana #10178

    View Slide

  9. 何があったかリスト
    ● Performance optimizations for mb_strlen and encodi
    ng conversion of SJIS, UHC, CP936, BIG5 text #10211
    ● Fix entries in SJIS multi-byte character length tables
    for bytes which do not start any valid 2-byte characte
    r #10230
    ● Update SJIS-mac mappings to use Unicode codepoi
    nts which were added after Unicode 1.0 #10264

    View Slide

  10. 何があったかリスト
    ● More performance increases for mbstring fun
    ctions on UTF-8 text
    ● Tweak up SIMD-accelerated version of
    mb_check_encoding for more speed
    ● Major overhaul of mbstring (part 30)

    View Slide

  11. 何があったかリスト
    ● More performance increases for mbstring functions
    on UTF-8 text
    ● Tweak up SIMD-accelerated version of
    mb_check_encoding for more speed
    ● Major overhaul of mbstring (part 30)
    ● mb_scrub does not attempt to scrub known-valid UT
    F-8 strings

    View Slide

  12. Tweak up SIMD-accelerated version of
    mb_check_encoding for more speed #10360
    ● UTF-8をSIMDでバリデーションするというプルリクエスト
    ● ここでこれの存在を知る
    Validating UTF-8 In Less Than One Instruction Per Byte
    – SIMDを利用してUTF-8のバリデーションを速くするという論文、すごいね
    – 日本語だと https://qiita.com/saka1_p/items/9719d71e702aed92a07c が
    詳しい
    ● 論文の著者の方によるリファレンス実装(JSONのパースができる)
    https://github.com/simdjson/simdjson

    View Slide

  13. SIMDとは
    ● 1つの命令で複数のデータに対して並列に演算できる
    – ベクトルとして扱うため、ベクトル演算なんて言ったりもする
    – CPUだと1つの命令で1つだけ(スカラー演算)
    ● その特性からマルチメディアに使われやすい
    – ゲームプログラミングとか画像・音声処理とか
    ● 普段は触らないが、コンパイラーによって最適化されるときに使われることも
    ある
    ● デメリットとしては、CPUアーキテクチャごとに違うこと

    View Slide

  14. UTF-8のおさらい
    Code Points 1st Byte 2nd byte 3rd byte 4th byte
    U+0000..U+007F 00..7F
    U+0080..U+07FF C2..DF 80..BF
    U+0800..U+0FFF E0 A0..BF 80..BF
    U+1000..U+CFFF E1..EC 80..BF 80..BF
    U+D000..U+D7FF ED..EC 80..9F 80..BF
    U+E000..U+FFFF EE..EF 80..BF 80..BF
    U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
    U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
    U+100000..U+10FFFF F4 80..BF 80..BF 80..BF

    View Slide

  15. UTF-8の特徴(一部分)
    ● いずれのバイトも0xF4を超えることはない
    ● 最大4バイト
    ● 2バイト以上の場合、最初のバイトの上位4ビットは文字のバイト数を示す
    – 1バイトはASCIIの範囲内(0x00-0x7F)
    ● 2番めのバイトは0xA0始まりだったり0x9F終わりなどの特徴的な部分が
    ある
    ● 3バイト目以降は0x80-0xBFだけ

    View Slide

  16. SIMDでUTF-8を扱う上で使うテクニック
    ● 「ニブル(nibble)」という単位 → バイトの半分の4ビット
    – 上位ニブル、下位ニブルなどと呼ぶ
    ● 飽和減算
    – PHPでいう、 if ($i < 0) $i = 0; などとして、非0を抽出したりする
    ● オーバーフローを利用した減算
    – 飽和減算の逆(普通の減算ともいえる)で、ピッタリ0のときにテーブル参照させたいとかで使っ
    たりする
    – ここで参照する論文では使いませんがこういうのを使ってるテクニックもあります
    ● バイトシフト
    – 複数のSIMDレジスタにまたがるときとかに使う
    ● テーブル参照
    – テーブルを引くとか言う

    View Slide

  17. SIMDでの「あ」のチェック例(正常系)
    ● UTF-8では0xE3 0x81 0x82の3バイト
    ● 0xF4を超えたバイトのチェック → 0xF4を飽和減算
    ● 0xE3の上位ニブル → 0xE → 0b1110 = 3byte
    – テーブルを引き、0b1110のときに3を指定する
    ● 0xCのときは0b1100となるので2になる
    ● 0xFのときは0b1111となるので4になる

    View Slide

  18. 「あ」の例(正常系)
    ● 2〜3バイト目、0x81 0x82
    – テーブルを次のように引き、ベクトルを定義すると、 3 0 0 となる
    ● 0〜7を1 (ASCII)
    ● 8〜11を0
    ● 12、13を2
    ● 14を3
    ● 15を4
    – 3を1バイト右にずらし1減らす → 3, 2
    – 3を2バイト右にずらし2減らす → 3, 2, 1
    – 結果、3 2 1という値が得られる、ここに0があったり、順番になってないと不正なUTF-8

    View Slide

  19. 「あ」の例
    ● 長い文字列のとき、例えば16バイト以上のときに前のバイト列を引っ張ってく
    る必要がある
    ● 0xEDと0x9Fおよび0xF4と0x8Fのチェックが必要
    – 0xF4はU+100000-U+10FFFFの最初のバイトにのみ出てくる
    ● 2バイト目が0x8Fが最大値
    ● 1バイト目の上位ニブルが0xEのときの0xA0、0xEDのときの0x9Fのチェック
    ● SIMDレジスタがまたがる場合に備えて1バイト右シフト
    ● これによって、すべてのSIMDレジスタが非0であればvalidなUTF-8

    View Slide

  20. SIMDでUTF-8のバリデーションの参照元
    ● 元論文: https://arxiv.org/abs/1902.08318v6
    ● 日本語で書かれている解説
    https://qiita.com/saka1_p/items/9719d71e70
    2aed92a07c
    ● 結構端折ったので参照してください。
    – 「あ」一文字だとスカラー演算したほうがいいし
    – 理解してないともいえる

    View Slide

  21. Add fast AVX2-based implementation of
    mb_check_encoding for UTF-8 #10436
    ● https://github.com/php/php-src/pull/10436
    ● ついにAVX2によるUTF-8のバリデーションを行うプ
    ルリクエストが作成される
    – PHP 8.3でx86_64アーキテクチャでAVX2が載ってると
    速くなる…!

    View Slide

  22. UTF-8 Validation optimization for NEON
    using mb_check_encoding #11076
    ● https://github.com/php/php-src/pull/11076
    ● てきめんが挑戦したプルリクエスト
    – ARMのNEONでUTF-8のバリデーションを高速化できない
    かというもの
    – 参考元: https://github.com/cyb70289/utf8
    – 性能がサチったのでペンディング状態になってる😭
    – 書いたブログ:https://tekitoh-memdhoi.info/views/872

    View Slide

  23. Add specialized UTF-8 validation function for hosts with
    no SSE2/AVX2 support #10452
    ● https://github.com/php/php-src/pull/10452
    ● SSE2/AVX2をサポートしていないCPUでなるべく
    高速にmb_check_encodingを行えるようにする
    – preg_match(‘//u’, $str) と同じ
    ● Raspberry Piを引っ提げて正常に動作することを
    確認しました

    View Slide

  24. Check UTF-8 validity for all constant
    strings on compile time #10853
    ● https://github.com/php/php-src/issues/10853
    ● 未解決なんだけど、valid UTF-8フラグをつけられるようにしたい
    よねっていうIssue
    – IS_STR_VALID_UTF8フラグをmb_check_encodingで立てられるよう
    にできないかなー?っていうもの
    – IS_STR_VALID_UTF8フラグとは、元はPCREで使っていたzval構造体に
    格納されるフラグ。UTF-8として正しいという意味
    ● それをZend Engine内部でも使うようになったのがPHP 8.3
    ● GH-10409のmb_scrubの件関係ある?って聞いたら、「ある」って
    返事もらえて、プルリクエスト作ってもらえたけどペンディング

    View Slide

  25. Add AVX2-accelerated UTF-16
    decoding/encoding routines #10488
    ● https://github.com/php/php-src/pull/10488
    ● 簡単に言えば、UTF-16のencoding/decodingで
    もAVX2を使えるようになったぞということ
    ● それ以外はわからん…

    View Slide

  26. mb_detect_encoding is more accurate on
    strings with UTF-8/16 BOM #10373
    ● https://github.com/php/php-src/pull/10373
    ● mb_detect_encodingの検出アルゴリズムを変え
    たというもの
    – mb_detect_encodingは色々変えてるので使ってる方
    は気をつけてください
    – そもそも文字コードは自動検出するべきではない

    View Slide

  27. mb_convert_encoding() returns inconsistent output before
    and after 0x0e 0x0f when converting ISO-2022-JP #10651
    ● https://github.com/php/php-src/issues/1065
    1
    ● mb_check_encodingのISO-2022-JP周りの処理
    でのIssue
    ● 半角カタカナをISO-2022-JPで無理やりねじ込む
    テクニックがあることを発見したので展開した

    View Slide

  28. Fix GH-10648: add check function
    pointer into mbfl_encoding #10828
    ● https://github.com/php/php-src/pull/10828
    ● @pakutomaさんのPull Request
    ● @alexdowadさんとfuzzingしまくってバグつぶしをひたす
    ら行うという地味に大変なタスクだったと思う
    ● 僕はJIS関連の指摘しかしてない
    ● なお、fuzzerのやり方も教えてくれてる

    View Slide

  29. Implement NEON-accelerated version of BLOCKCONV for
    lowercasing and uppercasing strings #11161
    ● https://github.com/php/php-src/pull/11161
    ● mbstring関係なしに、NEONというARMのSIMDをいじっ
    てたからレビューに加わりました。
    ● 内容としてはstrtolowerやstrtoupperなどで速くなる
    (ほかも速くなってるかも)
    ● ちょっと質問をして大丈夫だと理解したのでLGTM

    View Slide

  30. Fix UKRAINIAN LETTERS I in CP866 #11213
    ● https://github.com/php/php-src/pull/11213
    – CP866からUnicodeへの変換に「ウクライナ語の小文字i( ї)」を入れてくれというプル
    リクエスト
    – (当時)Twitterで調べて頂いたところ、CP866というのは、ウクライナ語・ロシア語・ベラ
    ルーシ語・ブルガリア語をサポートするというものだそう(ただ、すべてをサポートできる
    はずもなく中途半端な文字コードとなってる模様)
    – 残念ながら、ウクライナ語の小文字iはラテン文字のiを代用するものとして使っており、
    「 ї」は収録されていなかった
    – なるべく丁寧に説明、納得いただいたようでcloseしていただきました。
    ● 勉強になりました。

    View Slide

  31. More refactoring/fixes/optimizations for CJK text handling
    via mbstring #11259
    ● https://github.com/php/php-src/pull/11259
    ● mbfilter_cjkにまとめるというのが主なプルリクエス

    ● ここで、CP932のテーブルが統合されたことにより挙
    動が違うことをてきめんが発見、PHP 8.1へバック
    ポートをすることに

    View Slide

  32. mb_str_pad causes access violation
    ( 0xc0000005) in mbstring.dll #11567
    ● https://github.com/php/php-src/issues/1156
    7
    ● @nielsdos さん提案のmb_str_padでのバグ
    ● ちょっとNULLチェックで「こうするとバグらない
    ね」って指摘したけど、RFC読んだら間違ってた
    – Interned stringを使って解決してた

    View Slide

  33. After php8.1, when PDO::ATTR_EMULATE_PREPARES is true and
    PDO::ATTR_STRINGIFY_FETCHES is true, decimal zeros are no longer
    filled. #11587
    ● https://github.com/php/php-src/issues/11587
    ● @SakiTakamachiさんのIssue。pdo/mysql という、知らない部分の問題の
    切り分け
    – プルリクエスト書けるよというので、テストコードを書いて協力しました
    ● https://github.com/php/php-src/pull/11622
    – こちらで @Girgiasさんと@illuuu1994さんを呼んだ
    – @Girgiasさんが見てくれて、マージしてもらえた
    ● さきちさんはこのあとアクティブにphp-srcを見てくださっています

    View Slide

  34. Fix warning crc32.c on function
    declaration without a prototype. #11742
    ● https://github.com/php/php-src/pull/11742
    ● ext/standard/crc32.cのコンパイル時の問題
    – コンパイル時にWarning(PHPのじゃないよ!)が出てた
    – @illuuu1994さんがマージしてくれました。

    View Slide

  35. Fix '++nothing+crc' is not a
    recognized feature for target when
    compiling M1 / M2 macOS #11796
    ● https://github.com/php/php-src/pull/11742
    ● ext/standard/crc32.cのコンパイル時の問題
    – GCCだと意味のあるおまじないが、macOSのclangでは
    意味がないので外すプルリクエスト
    – @Girgiasさんにマージしてもらいました。

    View Slide

  36. SQLite3 callback functions cause a
    memory leak with a callable array
    #11878
    ● https://github.com/php/php-src/issues/1187
    8
    – http://doc.php.net/tutorial/local-setup.php を—
    enable-debugをつけた状態でコンパイルしたバイナリ
    で動かしたらmemory leakが発生したのを報告
    – @nielsdosさんが修正してくれた

    View Slide

  37. PHP 8.2でのmb_convert_kanaのdoc
    ● https://github.com/php/doc-en/pull/2647
    ● 実はPHP 8.2からできない組み合わせのときに
    ValueErrorをthrowするようになったというプルリク
    エスト
    ● @mumumuさんに助けてもらいました&マージして
    もらいました。thanks

    View Slide

  38. Fix typos discovered by codespell
    #12228
    ● 所謂 “fix typo” https://github.com/php/php-src/pull/12228
    – Unicode Consortiumのデータにtypoがあった
    – せっかくだから修正頼んでみればということで頼んでみた
    ● なんとKen Whistlerさんという中の人が直々にコメントをくださった
    – どのくらいすごい人かはユニコード戦記読んでみてください
    ● https://unicode.org/consortium/staff.html
    ● まとめると、「OBSOLETEとなっているものはたとえtypoだろうと修正しません」というもの
    – Fix typoでこんなドラマがあるんですね
    ● Fix typoやっていきましょう

    View Slide

  39. mb_str_padの追加
    $ ~/php_master/bin/php -r 'var_dump(mb_str_pad( 🎉
    " ", 3, "祝", STR_PAD_LEFT));'
    string(10) "祝祝🎉"
    str_pad関数のmbstring版。 https://wiki.php.net/rfc/mb_str_pad
    mb_str_pad(
    string $string,
    int $length,
    string $pad_string = “ “,
    int $pad_type = STR_PAD_RIGHT,
    ?string $encoding = null // nullだった場合にはmb_internal_encoding()
    ): string

    View Slide

  40. mbstringまとめ
    ● UTF-8への強化がものすごい
    – 世界中で使われている文字コードは世界中で研究されている
    ● 文字をベクトルとして読むとか考えもしなかった
    ● 論文まで読むことになるとはなあ…
    – 文字化けの心配だとするとUnicodeのバージョンくらい
    – UTF-8使おうぜ!!
    ● mb_str_pad関数が増えました
    ● mb_send_mailの挙動もちょっと変わってるかも
    ● mb_detect_encodingは更に変わってます(文字コードは指定するものです)
    ● ほかはほとんど内部的な変化・改善です

    View Slide

  41. まとめ
    ● 2022年12月から始まったこのゆるい関係でのコントリビュート、めっちゃ長かった
    ● コントリビュートでわかんないことあったらてきめん宛にXにでも連絡ください(ただしXだけでやりとりすると
    GitHubだけで見てる人が困惑するので共有はします)
    – 全部監視してるので「オッ」って思ったものはサポートしていく次第です
    – @SakiTakamachiさんとはそうしてました
    – phpusers-ja slackでもやりとりできます (@mumumuさんとはそうしてました)
    ● PHP Foundation所属のお二人(@Illuuu1994さん、@Girgiasさん)はさすが頼もしい
    – これ以外にもたくさんほとんど毎日やっておられます
    – 寄付のご検討を何卒よろしくお願いいたします!
    ● PHP 8.3のリリースマネージャーのうち、Jakub Zelenka (@bukka)さんもPHP Foundationのパートタイマーです
    ● 他にもコントリビュートしてる人たくさんいます!!
    ● PHP 8.3をお楽しみに

    View Slide