昨日の夜からSwiftの勉強を始めたんだが、文字列操作のループはPHP7の方がはるかに速い。
例えば数百文字の換字式暗号を総当たりするコードを書くとする。使われている文字または記号の種類が50種類あるとして、26のアルファベットを英語圏の頻度分析に基づき適当に散りばめ要素数50個の配列(alphabet)を作る。alphabetは毎回シャッフルするか順に並べ替える。
暗号文も1文字づつ分解し数字にして配列(angou)に納める。
そしてループの中で、配列(angou)から1文字づつ取り出し、該当するアルファベットを配列(alphabet)から呼び出して、1つの変数(mojiretsu)に代入(追記)していく。
PHP7なら $mojiretsu .= $alphabet[$angou[$count]] で結合していく。
Swiftなら、
(1) mojiretsu = mojiretsu + alphabet[angou[count]]
(2) mojiretsu += alphabet[angou[count]]
とする。
引数 count は、whileやforループのカウントを配列の添字として使用する。
平文に含まれていそうな文字列(例えば「paris」)を結合された平文文字列 mojiretsu の中から探し、該当があれば表示するという大凡当たりが付いている(ヒューミントチームが走り回って、シギント部隊がエアコンの中にいる(笑))時の総当たりコード。PHP7では preg_match() 、Swiftは contains() を使った。
これを100万回行うのにPHP7なら15秒。Swiftは swiftc -O コンパイルして1分10秒(笑)。
PHP7が非常に高速なのは周知の事実だが、コンパイルしてコレじゃ何もSwift(迅速)じゃない(笑)。
プログラミング経験のある人は contains() が遅いんじゃない?と思うだろう。私も真っ先にソコを疑い、ただ数字をカウントするコードに置き換えてみたがほとんど変化なし。そして判明したのは、
(1) mojiretsu = mojiretsu + alphabet[angou[count]]
(2) mojiretsu += alphabet[angou[count]]
が遅い(笑)。(2)の遅さはその後再現できなかった。
ただ文字を結合するだけの処理。で結局文字を末尾に追加する関数 append() が現時点でイチバン速い。
(3) mojiretsu.append(alphabet[angou[count]])
これで30秒まで短縮された。それでもPHP7の2倍も時間がかかる。
何かしら文字列操作周りのオーバーヘッドが大きいのかと思い、ループの中の結合はやめてとりあえず配列に入れ、ループを出た後に mojiretsu.joined() で配列を一括結合してみたが30秒を切ることはなかった。
Swiftのバージョンは5.1.3。
20年ぶりにプログラミング言語を乗り換えようと思ったんだが、PHP7は速い。そして時期バージョン8ではJITが導入され更に数倍速くなるらしいので、インタプリタの手軽さも含め、今後も私のメイン言語であり続けるだろうと感じた。
アプリは作らないし、手元のCLIプログラムとサーバーサイドのプログラムしか書かないので十分過ぎる。
Swiftは多分悪くない。現状iPhoneやiPadアプリばかり書かれていて、こういう「結果が出るまでループ継続」という用途に使われていないから揉まれていないだけだろう。バッテリー駆動の端末でするようなことじゃないし。ましてや100文字でも長文(笑)という人達が主な利用者だから、100万回も文字を結合するような需要もない。
PHP7なら毎時6,000万回の総当たりができる。何のノウハウも調整も最適化も必要とせず基本構文+iMacで。
『知的労働で完全無人収益化は可能か。【予告編】』のシステムをブログネタ用(笑)にSwiftで書き直そうかと思っていたんだが、PHP7とMySQLのまま行くことにした。とにかく軽くてノーメンテナンスで、イメージとしてはルブタン美女が座るコンシェルジュデスクのiMacのバックグラウンドでお金を生み出し続けるカンジ(笑)。
0コメント