• ベストアンサー

printf / sprintf のスタック消費量比較

こんばんは。スタックの消費量について質問させてください。 私の頭の中には「 printf は処理も遅くてスタックも沢山消費する」というイメージがあるのですが、標準出力ではなくメモリに書き出す sprintf の場合はどうなのでしょうか? printf と比較して処理が軽いのか、スタック消費量は少なくなるのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.4

組み込み系とのことですので、printf系関数のフルスペックの機能が必要とは思えません。 実際のところ、どれだけの機能がいるのでしょうか? 機能を制約すればするほど、スタックの消費量もプログラムサイズも少なくて済みます。影響の大きそうな機能を挙げると、 1. ワイド文字およびロケール対応 2. 浮動小数点数の書式化 3. 最小フィールド幅と精度 といった感じです。 1.と2.はすぐに思いつくでしょうが、3.が盲点になりがちです。特に最小フィールド幅は、値そのものが必要とする文字数を調べないと処理できませんので、いったんバッファに値そのものを整形した文字列を格納してから、出力している場合があります。 もちろん、機能の制約版を使うには、自分でそれを実装する必要があります。

Interest
質問者

お礼

回答ありがとうございます。そうですね、フルスペックのprintfは必要ありません。マイコンからPCに文字列を送る目的は (1)エラーコードを表示するため (2)センサで計測した値を確認するため (3)ログをはかせるため ですので、とりあえずは最大でも10進4桁と16進4桁も表示できれば十分だと思います。自作atoiもどきとputsでカバーして行こうと思います。

その他の回答 (3)

  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.3

printfの実装を確認してないので推測ですけど。 sprintfは利用側で書き出しバッファを用意して渡しますよね。 printfの場合はこの書き出しバッファを関数内で確保して書式化処理(sprintfと同様の処理)をした上でバッファの内容を標準出力に吐き出しているはずです。 問題はこのバッファをどこに確保しているかです。 可能性として3つ。 (1) mallocで確保、後でfree (2) 自動変数で(スタックに)確保 (3) 関数内で静的に確保 printfがスタックを1KBも使うなら(2)の方法を取っている可能性が高いですね。この場合はsprintfを使ってバッファを別に確保すればスタック消費量は減らせるでしょう。

Interest
質問者

お礼

回答ありがとうございます。コンパイラ(Yellow Soft YCH8)は買い物なので、ソースを見ることができません。 (1) はヒープ領域を使うことになりますが、ヒープ領域を確保しなくてもprintfが使えるところ見るとこれはなさそうです。 1KB、と書いたのはRTOS(NORTi 3 for YC)のマニュアルに"printfを使う場合は最低でも1024byteは必要です。"という説明があったからで、実際どれだけ消費するのかは計測しておりません。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

組み込みのプログラムで使うということであれば、フルスペックのものはひつようないかもしれませんね。 これのprintfの実装は見たことがないのですが、ライブラリ全体の大きさが小さいことで知られている uclibc というライブラリがあります。 参考になるかもしれません。

参考URL:
http://www.uclibc.org/
Interest
質問者

お礼

再度、回答ありがとうございます。 示していただいた参考URLからprintfの実装を追いかけてみましたが、だんだん深いところに入るにつれて私の理解を超えてきてしまいました。とりあえずは最大でも10進4桁と16進4桁も表示できれば十分なので、自作atoiもどきとputsでカバーして行こうと思います。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

いろいろな実装はありますが、printf/sprintf/vfprtinf/vfsprintf等々で 共通の下請けルーチンを使っていて、そこでメインの書式化処理を していたりするので、その比較はあまり意味がないと思います。 少なくとも、GNU/LinxuのglibcとかFreeBSDのlibcで使われている printf等は上記のような実装をしていました。

Interest
質問者

お礼

回答ありがとうございます。 そうですよね、同じ書式処理を持つ関数が複数あるなら、ルーチンをくくりだして共通化しますよね。 RAMの制約が厳しい組み込み系のプログラムを作っており、printfを使用するにはスタックを1024バイト程度用意する必要があるため、スタックを減らす方法を模索しています。

関連するQ&A