ブックマーク / hnw.hatenablog.com (16)

  • PHPとPythonとRubyの連想配列のデータ構造が同時期に同じ方針で性能改善されてた話 - hnwの日記

    PHPPythonRubyの連想配列のデータ構造がそれぞれ4〜5年ほど前に見直され、ベンチマークテストによっては倍以上速くなったということがありました。具体的には以下のバージョンで実装の大変更がありました。 PHP 7.0.0 HashTable高速化 (2015/11) Python 3.6.0 dictobject高速化 (2016/12) Ruby 2.4.0 st_table高速化 (2016/12) これらのデータ構造はユーザーの利用する連想配列だけでなく言語のコアでも利用されているので、言語全体の性能改善に貢献しています1。 スクリプト言語3つが同時期に同じデータ構造の改善に取り組んだだけでも面白い現象ですが、さらに面白いことに各実装の方針は非常に似ています。独立に改善に取り組んだのに同じ結論に至ったとすれば興味深い偶然と言えるでしょう2。 稿では3言語の連想配列の従来実

    PHPとPythonとRubyの連想配列のデータ構造が同時期に同じ方針で性能改善されてた話 - hnwの日記
    asakura-t
    asakura-t 2021/01/11
    perlは5.26(2017.05)で64bit環境向けに変更していたらしい>https://perldoc.jp/docs/perl/5.26.0/perl5260delta.pod /ハッシュの順番は5.18の時に積極的にランダム化されてた>https://perldoc.jp/docs/perl/5.18.0/perl5180delta.pod
  • PHPのround関数とは一体なんだったのか - hnwの日記

    (7/3 14:05追記)Javaに関する記述について誤認があったので盛大に書き換えました。Java 6、Java 7、Java 8それぞれで実装が変わっていたようです。 (7/13 23:55追記)記事中ではroundを四捨五入と言い切ってしまっています。これは筆者がC99のroundを基準に考えているためですが、言語によっては偶数丸めになっているround関数も珍しくありません。ご注意ください。 PHPのround関数について、ネット上で次のような記述を見つけました。 PHP 四捨五入の計算を間違える唯一の言語として畏れられていましたが、そのバグは治っているかもしれません(治ってないかもしれません) 主要なプログラミング言語8種をぐったり解説 - 鍋あり谷あり 各言語を面白おかしく紹介する内容とはいえ、ずいぶん雑な理解だなーという印象です。ゆるふわな話だけでPHPがdisられ続けるの

    PHPのround関数とは一体なんだったのか - hnwの日記
    asakura-t
    asakura-t 2016/07/04
    perlだとMath::BigIntかMath::BigFloatだろうけど、実装どうなんかな。
  • PHP 5.4.4から==の挙動が一段と難しくなりました - hnwの日記

    PHPの==は両辺を適当に型キャストしてから比較するような演算子です。この型キャストの規則は難解すぎる上にドキュメントも不十分なため、PHPプログラマでも完璧に理解している人はほとんど居ないくらいの印象です。バグの原因になりかねないため、なるべく==を使わないようにしているPHPプログラマも多いはずです。 ところで、この==演算子の挙動がPHP 5.4.4から変更されていることはあまり知られていません。稿ではこの内容を紹介します。 Bug #54547 の騒動 まずはこの仕様変更の経緯を紹介します。 2年ほど昔、Hacker Newsで2^63付近の整数に対応する文字列をPHPで比較したときの挙動がおかしいというスレッドが盛り上がったことがありました。具体的には、PHPでは「'9223372036854775807' == '9223372036854775808'」がtrueになるとい

    PHP 5.4.4から==の挙動が一段と難しくなりました - hnwの日記
    asakura-t
    asakura-t 2014/08/11
  • 第59回PHP勉強会でPHPのマルチバイト処理の分類について発表しました - hnwの日記

    去る25日の金曜日に第59回PHP勉強会@東京で発表してきました。以下が発表資料(少し修正しました)です。 発表資料:「PHPのマルチバイト処理 ― 分類と落とし穴」(slideshare版)(PDF版) 久々のPHP勉強会だったので張り切って発表しに行ったのですが、他の人も同じ考えだったようで、編の発表が3、ちょっとピザべた後に発表5という大盛況でした。 僕の発表内容は、最近PHPのバイナリが何系統の文字コード処理を含んでいるかについて調べたので、それをまとめたものです。関連しそうなバグエピソードを絶賛受付中です。 他の方の発表では、@yandoさんのキャッシュとページネータの話題は明日から使えそうなくらいの役立ち情報でした。(「Zend_Cache Zend_Paginatorの発表をしました@PHP勉強会 : candycane development blog」) また、@

    第59回PHP勉強会でPHPのマルチバイト処理の分類について発表しました - hnwの日記
  • MySQLの自前strtod実装がタコすぎる - hnwの日記

    MySQL5.1のソースコードを確認していたところ、浮動小数点数の10進表記から浮動小数点数への変換処理に実装上の問題点を見つけました。浮動小数点数処理の典型的な落とし穴にはまっていて、計算の途中で精度を落としてしまっています。 これは古くから知られているバグのようで、下記URLから判断すると2007年末頃には修正コードが開発系ブランチに入っていたようです。しかし、その後のんびりしていたのか、2010年4月のMySQL5.5.3で初めて安定版としてリリースされました。また、今のところ5.1系へのバックポートは出来ていないようです。 Worklog :: WL#2934 >> Make/find library for doing float/double to string conversions and vice versa MySQL Lists: commits: bk commit

    MySQLの自前strtod実装がタコすぎる - hnwの日記
    asakura-t
    asakura-t 2012/04/09
  • PHPの新しいround関数を読み解く (2)pre-roundingの意味 - hnwの日記

    (2011/10/18 01:50)「他の言語で試してみる」「誰が正しいのか?」を追記しました。また、初心者への対策と強調しすぎて誤解を招いた気がしたため、少し表現を変更しました。 前回記事「PHPのround関数を読み解く (1)丸め桁数が大きすぎ・小さすぎる場合」に引き続きPHPのround関数の処理を解説していきます。今回は、PHP5.3のround関数で最も特徴的なpre-rounding処理を追いかけていきましょう。 pre-roundingとは pre-roundingとは、与えられた数の丸め処理を行う前に、与えられた数をいったん10^n倍して10^14以上10^15未満の数にして整数への丸めを行うことです。pre-rounding処理のあとで、改めて来の丸め処理を行います。 ちなみに、pre-roundingという単語は一般的な単語ではありません。少なくとも僕はPHPのro

    PHPの新しいround関数を読み解く (2)pre-roundingの意味 - hnwの日記
    asakura-t
    asakura-t 2011/10/17
  • PHPの日付文字列の解釈ルールがドキュメント化されました - hnwの日記

    PHPのstrtotime関数やDateTimeクラスは、様々なフォーマットの日付文字列を解釈し、時刻として取り扱うことができます。たとえば次のような文字列を解釈することができます。 "Wednesday July 23rd, 2008"(=2008年7月23日) "first Wednesday July 23rd, 2008"(=2008年7月30日、PHP5.1.0以降) "first Wednesday of July 23rd, 2008"(=2008年7月2日、PHP5.3.0以降) こうした日付の解釈はPHP独自の実装です*1。当初はGNUの日付記法に準拠していたようですが*2、今や別物といっていいでしょう。にもかかわらず、これまで解釈ルールの詳細を説明するドキュメントが存在しない状態が続いていました。 そのため、仕様を推測する根拠はstrtotime関数のサンプルコードとP

    PHPの日付文字列の解釈ルールがドキュメント化されました - hnwの日記
    asakura-t
    asakura-t 2011/02/17
    ……テストはどうなってるんだろ。ひょっとしてテストがないのかな。。。
  • mb_ereg_replace関数でe修飾子を使う際の注意点 - hnwの日記

    mb_ereg_replace関数でe修飾子を使ってevalする場合の注意点をまとめてみました。 概要 マニュアルの下記引用部にもあるとおり、mb_ereg_replace関数はe修飾子の指定があっても特にエスケープなどを行いません。 信頼できない入力に対しては、絶対に e 修正子を使用してはいけません。 (preg_replace() と同様、) 自動的なエスケープは行いません。このことを忘れていると、自分の書いたアプリケーションにリモートコード実行の脆弱性を作りこんでしまうことになります。 PHP: mb_ereg_replace - Manual preg_replaceでe修飾子をつけた場合、後方参照について自動でaddslashes相当のエスケープを行ってくれます(「例えばPHPのpreg_replace関数でe修飾子を避ける」参照)ので、この点において両者は挙動が異なっているわ

    mb_ereg_replace関数でe修飾子を使う際の注意点 - hnwの日記
    asakura-t
    asakura-t 2011/02/09
  • 日付と時刻の豆知識 (1)暦と地球の運行 - hnwの日記

    WEB+DB PRESSに連載中の「PHP転ばぬ先の杖」も次で5回目です。表紙にも載せて頂きましたが、次号Vol.60では「日付と時刻」をテーマに書きました。12月23日発売予定だそうですので、よろしくお願いします。 ところで、今回の原稿のために調べたものの、雑誌記事には反映できなかった内容がいくつかありました。いわばボツ原稿のようなものですね。せっかくですので、これを何回かに分けて紹介します。1回目は暦に関する話題です。 小さい頃、僕は春分の日と秋分の日の日付が毎年違うのが不思議でした。今説明するとしたら、「地球の公転周期はピッタリ365日ではないため、地球は1年後の同じ日付に同じ位置にないから」ということになるでしょうか。地球の公転周期はおよそ365.24日ですから、春分や秋分といった天文的な位置は同じ日付には対応せず、毎年ズレが生じます。逆に言えば、このズレを補正する仕組みがうるう年

    日付と時刻の豆知識 (1)暦と地球の運行 - hnwの日記
    asakura-t
    asakura-t 2010/12/13
    つい最近見かけた「バイナリ歴」を思いだした。http://www.finetune.co.jp/~lyuka/interests/essay/binarian/
  • 例えばPHPのpreg_replace関数でe修飾子を避ける - hnwの日記

    (2015/04/19追記)e修飾子はPHP 5.5からdeprecatedになっています。また、PHP7からは廃止されます。 PHPのpreg_replace関数では、e修飾子が利用できます。これはPerlから輸入された機能で、置換後パターンの文字列をPHP文法に従って評価する(evalする)というものです。Perlを知らないとあまり使わない機能かもしれませんが、Perlを知っているとPHPでも使いたくなるのではないでしょうか。記事では、preg_replace関数でe修飾子を使う場合の注意点を指摘し、代替案を示します。 preg_replace関数のe修飾子 preg_replace関数のe修飾子は次のような機能です。 e 修飾子を設定すると、preg_replace() は、参照先の対応する置換を行う際に replacement 引数を PHP コードであるとして取り扱います。re

    例えばPHPのpreg_replace関数でe修飾子を避ける - hnwの日記
    asakura-t
    asakura-t 2010/08/16
  • PHPのPCRE関数での\Q,\EはPerlと同一ではない - hnwの日記

    Perl正規表現で利用できる便利なエスケープシーケンスとして、\Qと\Eがあります。これはメタ文字の解釈を止めたり、その解釈を再開したりするものです。「man perlre」には次のような例が出てきます。 /$unquoted\Q$quoted\E$unquoted/ この正規表現は変数$unquotedと$quotedの値を利用しますが、利用のされかたが異なります。$unquotedの値はそのまま正規表現として解釈されますが、$quotedの値は文字列一致となります。 #!/usr/bin/perl -w use strict; use Data::Dumper; my $quoted = '.?'; my $unquoted = '.'; my $subject = "a.?a"; print $subject =~ /^$unquoted\Q$quoted\E$unquoted$/;

    PHPのPCRE関数での\Q,\EはPerlと同一ではない - hnwの日記
    asakura-t
    asakura-t 2010/08/10
  • PCREはUnicode文字プロパティをサポートするとは限らない - hnwの日記

    (2011/05/19追記)CentOS5のpcreパッケージについて言えば、2010年7月以降Unicode文字プロパティが有効になっているそうです。安心ですね!(via「 CentOS5.5でCakePHP1.3系のInflector::slugを正常動作させる方法 - Lism.in * blog - nekoya (id:studio-m)」) PCREというのは、Perl互換の正規表現ライブラリです。PCREは例えばPHPのpreg系関数で利用されていますし、他の処理系でも多く利用されているかと思います。ところで、PCREの挙動は環境ごとに異なる可能性があることをご存知でしょうか。具体的には、Unicode文字プロパティをサポートする環境としない環境とがあり、同じ正規表現でも挙動が変わることがあります。僕はそんなことを考えた事もなかったので、ビックリしました。 同じ原因で、以前の

    PCREはUnicode文字プロパティをサポートするとは限らない - hnwの日記
    asakura-t
    asakura-t 2009/06/30
  • 自然順ソートを行うPHPワンライナー - hnwの日記

    PHPの豊富すぎる組み込みの関数の中でも、natsort関数はかなり高機能な関数の一つだと思います。他の言語なら体に組み込まれることは有り得ないのではないでしょうか。 natsort ― "自然順"アルゴリズムで配列をソートする 説明 bool natsort ( array &$array ) この関数は、人間が行うような手法でアルファベットまたは数字の文字列の順番を キー/値の関係を保持したままソートします。 これは、"自然順(natural ordering)"と呼ばれているものです。 このアルゴリズムと (sort() を用いた) 通常のコンピュータ文字列ソートアルゴリズムの違いを示す例を以下に示します。 http://docs.php.net/manual/ja/function.natsort.php 今回のお題は、このnatsortを使ったワンライナーです。 自然順ソートが

    自然順ソートを行うPHPワンライナー - hnwの日記
    asakura-t
    asakura-t 2009/06/23
  • UTF-8→SJIS/EUC-JPの重複文字をまとめてみた - hnwの日記

    文字エンコーディングの変換を行うと、異なる2文字が同じ文字に変換されることがあります。このような文字を重複文字と呼ぶことにします。UTF-8→Shift_JISおよびUTF-8→EUC-JPについて、重複文字を自分用の資料としてまとめてみました。 MacOSX上のPHP5.2.9での実験結果ですが、プログラミング言語や環境によらず気をつけるべき文字一覧ということになると思います。 色のついている部分が重複している部分です。「-」となっているのは変換できなかった文字です。また、ヘッダのカッコ数字ごとに文字エンコーディング変換に利用した関数が異なります。詳細は下記の通りです。 (1) mb_convert_encoding($char, "Shift_JIS", "UTF-8") (2) mb_convert_encoding($char, "SJIS-win", "UTF-8") (3) i

    UTF-8→SJIS/EUC-JPの重複文字をまとめてみた - hnwの日記
    asakura-t
    asakura-t 2009/05/07
    何で今更?……と思ったけど、そろそろPHP界隈でも阿鼻叫喚が聞こえてくる時期なのかな(PHP6で)。Shift_JISは使わずCP932を使っておけと昔から言われているのに。まだまだ啓蒙が足りないらしい。
  • PHPの==演算子をわかりやすくするパッチ - hnwの日記

    PHPの==がキモい件」でも書きましたが、PHPの==は数値っぽいものに対してアバウトな比較を行う演算子です。 一方で、他の言語の==演算子は正確な比較を行うものばかりだと思います。他の言語の経験者がPHPのソースコードを読み書きする場合に、PHPの==演算子の挙動を想像することは困難です。 つまり、PHPの==演算子の問題点は、他の言語と異なる意味にも関わらず同じ表記を採用していることにあります。見ただけで「アバウトな比較を行う」と想像できれば混乱は避けられるはずです。 そこで、PHPにパッチを当て、新たな演算子を導入してみました。 <?php if ("01" ≒ "0x1") { echo '"01" ≒ "0x1" is true',"\n"; } if ("01" ≈ "0x1") { echo '"01" ≈"0x1" is true',"\n"; } if ("01" ≉

    PHPの==演算子をわかりやすくするパッチ - hnwの日記
    asakura-t
    asakura-t 2009/04/02
    素晴らしいw
  • array_unique関数がPHP5.2.9から後方互換性を失いました - hnwの日記

    追記(2009/06/26):PHP 5.2.10以降、この問題は修正されています。「array_unique関数がPHP5.2.10から後方互換性を取り戻します」も併せてご覧ください。 2/26にPHP5.2.9がリリースされましたが、このバージョンからarray_unique関数が後方互換性を失いました。この関数を利用しているアプリケーションは、PHP5.2.9以降のバージョンでは新たなバグに悩まされるかもしれません。 5.2.9RC1の頃にこの仕様変更に気づいて「PHP Bugs: #47370: array_unique has backward compatibility problem, and SORT_REGULAR is confusing」で指摘してみたんですが、相手にされませんでした。 その後もid:moriyoshiさんが元の動作をデフォルト動作にするよう、中の人と

    array_unique関数がPHP5.2.9から後方互換性を失いました - hnwの日記
    asakura-t
    asakura-t 2009/03/16
    毎度のことだけど。だからできるだけPHPは使いたくないのに。。。
  • 1