web-dev-qa-db-ja.com

ジュリアでは、@ printfが関数ではなくマクロなのはなぜですか?

Juliaでは、書式設定された文字列を出力する構文は次のとおりです。

@printf("Hello %d\n", 5)

なぜ@printf関数ではなくマクロ?さまざまな数の引数を受け入れることができるようになっていますか?

55
Ben Hamner

可変数の引数を取ることは、通常のジュリア関数[ 1 ]では問題になりません。 @printfはマクロであるため、コンパイル時にフォーマット文字列を解析および解釈し、その特定のフォーマット文字列のカスタムコードを生成できます。 Cのprintf関数がフォーマット文字列を再解析および再解釈することに気付かない場合があります毎回printfを呼び出します。それがそれと同じくらい速いという事実は、非常識なポインタプログラミングの小さな奇跡を表しています。真剣に、あなたの最も近いlibcのprintf実装を見てください。それは完全にナッツです。

ジュリアは異なるアプローチを使用します:@printfは、フォーマット文字列をそのフォーマット仕様に固有の効率的なコードに変換するマクロです。考えてみると、printfスタイルのフォーマット文字列は、実際には、固定数とタイプの引数を取り、特定の方法でそれらを出力する関数を表現するための単なる方法です。 format stringは関数であり、printf自体ではなく、概念的には関数ジェネレーターであり、フォーマットをフォーマッターに変換することに注意してください。これがすべてCのランタイム関数に詰め込まれているという事実は、Cの唯一の合理的なオプションであるため、少し不一致です。間違った数またはタイプの引数をCのprintfに渡すことにより、これは、コンパイラがprintf形式のセマンティクスを理解するために特別に設計されているためです。

理論的には、ジュリアの@printfは、カスタムコードを生成するため、Cよりも高速にできますが、実際には、Cを一致させるのに苦労しました。しかし、それは私たちのI/Oシステムの現在の設計とその使用方法によるものであり、固有の制限によるものではないと思います。ただし、I/Oの部分はオーバーホールが原因であり、それが起こると、実際には@printfはマクロです。

101
StefanKarpinski

パフォーマンス用です。 printfマクロは、一定の形式の文字列(例:"Hello %d\n")その文字列に最適化されたコードを生成します。

5
ivarne