• ベストアンサー

関数内の宣言について

あまりオープンソース等を見たことがないのですが、できるだけ速度を上げたくて、代数を大量に使用する関数の場合 その中の変数にstaticを明確に書いておくと速くなるんじゃないかなと思ったんですが、 単純な処理なのでコンパイラが自動的に選択してるのかなとも思ったのですがどうするべきでしょうか。

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

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

>その中の変数にstaticを明確に書いておくと速くなるんじゃないかなと思った 実際にそうなるかどうか、実験してみてはいかがでしょうか。 なお、 >コンパイラが自動的に選択してるのかなとも思った この文が、staticな変数とそうでない変数をコンパイラが自動的に選んでいる、 と読めばよいのでしたら、内容が誤っています。 staticと人間が書いていないのにコンパイラが自動的にstaticと解釈してくれる、 という都合のいい話はありません。

msms001999
質問者

お礼

ご回答ありがとうございます。 早速、実験してみました。 VC++でDebugモードclass test{int a[1000];}; をclass内の関数で10個ほど宣言してみると staticをつけた結果/そうでない場合だと30倍ほど速くなっています。 同じくReleaseモードで実行した結果、当然Debugより格段に速くなりますが速度の比は1/2以下に低下いたしました。つまり何らかの最適化が行われているということかなと思いました。 >>コンパイラが自動的に選択してるのかなとも思った 適当に考えたんですが、メモリ領域の保持がなされる(呼び出すときは初期化された状態に)とか思って書きました。

その他の回答 (2)

回答No.3

考えもなしにstaticにしてしまうと、リエントラント前提で作成された関数の場合に不都合を起こす可能性があります。

参考URL:
http://ja.wikipedia.org/wiki/%E3%83%AA%E3%82%A8%E3%83%B3%E3%83%88%E3%83%A9%E3%83%B3%E3%83%88
msms001999
質問者

お礼

ご回答ありがとうございます。 シングルスレッドの処理で且つ外部からの呼び出しを一切受けない場合に限るぐらいの条件は考えてましたが、リエントラントというのは設計をするとなると、例えばある関数を意外な所で意外な使用方法をとる必要がでてきたりしそうですから、抽象classとかだと頻繁に考えたりするのかなと思いました。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

>その中の変数にstaticを明確に書いておくと速くなるんじゃないかなと思ったんですが、 可能性としては、考えられますが、それがどの位、処理速度向上につながるかは、#1のかたが言われるように実際にやってみた方がよいかと思います。 処理速度を向上させる場合、一般的には、以下のような方法をとります。 1.各処理でどのくらい時間がかかっているかを、各処理毎に計測する。 2.その中で、処理速度に大きな影響を与えているところを探し出す。 (一般的にはその場所をボトルネックと言っています。) 3.そのボトルネックを解消する方法を考える。(アルゴリズムの変更もその中に含まれます)

msms001999
質問者

お礼

ご回答ありがとうございます。 処理速度の向上の必要がある場合、簡単な所なら感覚的に変更しても向上する可能性があると思いますが、計測してみるとか観測的になるべくしてきます。 致命的?な悪影響が出るほどのソースは見たことが無いんですが、ボトルネックは覚えておきます。

関連するQ&A

  • static付き宣言の初期化

    static付きの宣言をした場合の変数の初期化について教えてください。(ANSI-C) int func(void) { static int si; static char sca[10]; static char *scp; /* 何らかの処理 */ return 0; } このように関数内でstatic付きで宣言したとき、変数はどのように初期化されますか? siは0、sca[0]からsca[9]までは'\0'、scpはNULLで初期化されますか? また、このようなstatic付きの宣言が関数の外にあった場合は、どのように初期化されますか?

  • 現コンパイラがサポートしていない関数について

    現コンパイラがサポートしていない関数について 現コンパイラとしてC++ビルダー2009付属のコンパイラBCC32を使用している。 ストリームエデイタ(SED)のソースコードを入手して,色々調べてみている。 SEDのなかで「intdos」関数を使用している。 現コンパイラはintdosをサポートしていない。dos.hのなかでintdosは定義されていない。 SEDの中で使用している intdosのAH=4EHはfindfirst関数に、 intdosのAH=4FHはfindnext関数に、に置き換えられることがわかった。 SEDではpsp(プログラム・セグメント・プレフィックス)のアドレスがグローバル変数_pspに格納されていることを使用している。pspのアドレスはintdosのAH=51HまたはAH=62Hで取得できる。 さて質問です。intdosが使用できないときに、pspのアドレスを取得する方法を教えて下さい。 よろしくお願いします。

  • C言語での変数宣言の場所

    今まで2年ほどJavaを使っていましたが、最近になってCを使う必要が出てきました。Cは大学の頃に授業で学んだ程度のレベルです。 それはさておき。 JavaやC++ではメソッド内のどの場所ででも、新たな変数を宣言して使用できますが、Cでは関数内の最初の方でしか宣言できないですよね? 先日、その事を意識せずに、Javaと同じように変数を関数の任意の場所で宣言しているようなCのソースを書き、gccでコンパイルしたところ、コンパイルが通ってしまいました。 その時のファイルは「.c」ファイルです。 このソースはC++のソースとして、コンパイラが認識してしまったのでしょうか?拡張子が「.cpp」ではなく「.c」のままでしたが、コンパイラは拡張子ではなく、ソースを読み込んでから、そのプログラムがCなのかC++なのか判断しているのでしょうか? いまいちピンと来ないので、どなたか解説お願いします。

  • datediff関数?

    あるオープンソースで $変数 = datediff( time() ,$変数); という関数があります。 また、その出力が 0d 16:00 という風になっています。 phpにはdatediff関数というものが無いかと思いますので関数を自作しなければならないと 思います。 そのユーザー定義関数が無いということは考えられますでしょうか? 私が見つけられないだけでしょうか? ご検討のつく片宜しくお願いします。

    • ベストアンサー
    • PHP
  • 『関数内static変数』の別名って??

    1、『関数内static変数』の別名で一言の呼び方ってありますか?? 2、『static変数』と呼ぶときは通常、ファイル内で有効な変数(この場合だとファイルローカルな変数??)と考えてよいのですね? おねがいしますm(_ _)m

  • Java main関数内でStatic変数使えない

    JavaのStatic変数について質問です。 Main関数の中でStaticな変数を定義しようとしたところ、 final修飾子しか使えませんというエラー文言が出ます。 Main関数内でわざわざStatic変数を使用する必要はないのですが、 出来ないと言われると何故だろうと思ってしまいます。 どなたかご説明いただけないでしょうか? -------------------------------------------------------------------- class Test { public static void main(String[] args) { // 宣言時Staticは使えなく、finalでしか定義できないとエラーが出る Static int test_val = 10; // 表示 System.out.println(test_val); } }

    • ベストアンサー
    • Java
  • static 関数のメモリ使用量

    会社で過去のプログラムを参考に新規開発を行っているものですが、 旧プログラムは関数宣言でstaticを使用しており、関数のカプセル化をしている。 旧プログラムをみならい、staticで関数を宣言したのですがレビュー時にstaticで関数を宣言した場合、 『メモリーを多く使用するのでは?』と質問されたのですが回答が見つかりません。 詳しい方教えていただけますか? プログラムはファイル分割されており、同一関数名は存在している。 コンパイラーはgccです。

  • 未使用引数の注意文出力を回避するには

    他種CPUの古いCソースをSH版に移植中なのですが、日立SHCコンパイラの オプション -ME でメッセージ出力抑制を解除すると大量の注意文が出力されて対処に 困っています。 その中で、C0012 (I) Unused variable "~" について、関数の取り合い仕様で引数が規定されているが、関数内処理では使われない 場合に注意文の出力を回避したいのですが、何かいい対策案ないでしょうか? int func( int a,int *b ){ return(0); } これまで分かっていることは 1)コンパイラは出荷済み他製品と共通なのでバージョンを上げられない。 2)-NOME=12 の出力抑制オプションは自動変数の未使用も検出しなくなるので不可。   (コンパイラも現状バージョンは番号指定に未対応です) 3)return(0); の後ろに a=0;b=0; と入れるとC0003 (I) Unreachable statementが出る。 4)変数属性の unused はコンパイラが未対応。 対策案の一つとして、関数内に if(a==0){} if(b==0){} を入れるというのがあるのですが、余分な機械語を生成しないか不安で検討中です。

  • 関数内、ファイルのstatic変数

    関数内で、static変数を宣言した場合に、その値は保持されると 思いますが、その関数の外からポインタで見る場合にその値は 保証されるのでしょうか? (必ず同じメモリ上に配置されるのでしょうか?) また、関数とファイル内static変数においてスコープ以外に 取り扱いが変わったりするのでしょうか? (配置されるメモリ空間等) よろしくお願い致します。

  • 変数の宣言をグローバルにしないと変数の参照が出来ま

    変数の宣言をグローバルにしないと変数の参照が出来ません。 ソース全体はカプセル化のために即時関数で囲っています。 function found内で小数点第三位までで四捨五入するようにする処理が共通なので関数化したのですが、 var gramNumを外で宣言しないと参照できずにgramNumが定義されていないと出てしまい困りました 関数スコープの影響だと思い宣言を外に出したのですが、それでも定義されていないと出て、 最終的にグローバル変数にしてやっとうまくいきました。 スコープは自分より上のスコープの変数は参照できるようですが if(xGramEmptyFlag === true) {ないの式がroundの上にあるvar gramNumを参照する場合、 if分の中にある式の一つ上のスコープなので参照できると思ったのですがなぜできないのでしょうか? varはブロックスコープがないので一つ上ではなく同じスコープにあることになるのでしょうか? ただその場合も同じスコープの変数は参照できるのではないのでしょうか?

専門家に質問してみよう