見出し画像

たかが strlen() されど strlen()

C言語に慣れている人であれば文字列の長さを返すstrlen()なんて、あっと言う間に書けてしまうでしょうし、コードとしても短いものなので、インライン展開ができるようにヘッダの中にコードがあるんじゃないかとヘッダを読み始めました。

C言語教室 番外編2 - 第5回の課題について - stelen()を調べ始めたキッカケ

strlen()を使う時は”string.h”をincludeするのはリファレンスにも書いてあるお約束です。さっそく”string.h”を開くと標準ライブラリあるあるなのですが、互換性と環境に依存する部分を切り分ける複雑な条件式が並んでいて、実はstrlenはラップされた名前で実際に実装されている名前に変換されていました。

「ホウホウ」ヘッダにソースがなくてライブラリに実体があるのであれば、インライン展開は無理だな。高速にするためには関数呼び出しのコストよりアセンブラとかで書いたほうが早いということなのかなと、今度はgccで使うライブラリのソースコードを探し始めました。

目当てのコードを探し当て読み始めると、アセンブラとかを使うのではなくて、それなりにややこしいことをしているC言語で書かれていた関数を見つけました。64ビットCPUでは8ビットに対する処理も64ビットの処理もほぼ同じコストで実行できます。ですので64ビットCPUで8ビットずつ処理するとおよそ8倍のコストがかかってしまうわけです。そこでCPUのビット数に応じて一度に複数文字分に対して終端文字である’\0’が含まれているかを調べてしまうのです。

JUNのブログ

上記のブログではベンチマークの結果もあるのですが、それによると64ビットCPUの場合、8倍どころか10倍近くの高速化が図れていることを確認しています。メモリからレジスタに読み込む際に、キリの悪いアドレスからの読み出しには余分のコストが発生しているからなのでしょう。

決まりきった処理であっても「CPUの気持ち」になって考え直せば、より効率的な方法が見つかるものなんですね。なかなか勉強になりました。

strlen

strlen | Programming Place Plus C言語編 標準ライブラリのリファレンス

ヘッダ画像は、以下の素材から作成しました。
https://www.irasutoya.com/2013/02/blog-post_2646.html
https://www.irasutoya.com/2015/01/blog-post_856.html


この記事が気に入ったらサポートをしてみませんか?