• ベストアンサー

C言語の型による処理速度の違い

short int型よりint型。float型よりdouble型の方が 扱えるサイズは広いにも関わらず処理速度が速いと 聞いたのですが、それは本当でしょうか? もしそうならなぜそうなるのでしょう? (一度BCCでfloatとdoubleの処理速度を計ったらfloatの 方が少し早かったですが・・) 高速なプログラムを書く必要の出たときのために型に よる処理速度を教えてください。

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

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

> 高速なプログラムを書く必要の出たときのために型に > よる処理速度を教えてください。 処理系に依存しますし、処理系のマニュアルにも記載されていない場合が多いので、自分でコンパイル結果を見ながら確認する必要があります。 組み込み用の処理系では、マニュアルにこの辺りの解説が書かれているものをよく見かけます。 一般的には、short型がint型より小さい場合は、何らかの演算の前には汎整数拡張によってint型に暗黙の型変換が起こりますので、その分だけ遅くなる場合があります。ただし、プロセッサのアーキテクチャによっては、こうしたオーバーヘッドが発生しないものも普通に存在します。 浮動小数点型の場合ですが、標準化以前のC言語では、float型はいったんdouble型に暗黙の型変換が行われてから演算していたのですが、標準Cではfloat型はfloat型のまま演算してもよいことになり、多くの処理系はそのようになっています。 また、可変個実引数や、関数原型のない関数の引数としてfloat型の値を渡した場合、既定の実引数拡張によってdouble型に暗黙の型変換が起こります。 いずれにしても、暗黙の型変換が発生し、それにコストがかかるような処理系では、クリティカルな処理では大きな影響が出ることが十分考えられます。

amazontester
質問者

お礼

かなり参考になりました。ありがとうございます。

その他の回答 (4)

  • moritan2
  • ベストアンサー率25% (168/670)
回答No.5

対象となるマシンや言語の実装によって違います。 一般的にインテルのCPUでは浮動小数点計算はdoubleの方が高速ですが、ゲーム機では断然 float の方が速いです。PS2とか今は亡きドリームキャストにはfloatを4つ同時に計算できるベクトル演算機を内蔵していますから。

amazontester
質問者

お礼

なるほど・・・。私のCPUはAMDのデュロンだったの でfloatの方が早く出たのかもしれません。PS2が floatの方が早いというのは面白いですね。

回答No.4

高速なプログラムを書くためには、アルゴリズムやデータ型を気にした方が遙かに有用だとは思いますが。 まず、int に対しては、「そのプロセッサで最も自然なデータの長さを int にする」傾向があります。このため、わざわざ型変換のはいる可能性のある、shot int よりも、速い場合が多いですね。 double に関しては、標準C言語では、浮動小数点データの基準は double だからというのがひとつあります。 たとえば、数学系の関数の返値や引数はすべて double です。また、小数点を含んだ定数( 0.1 とか)は、特に指定がない限り、double 型のデータです。(0.1f だと float 型の定数です) よって、 float x = 0.1; // x = (float)0.1; という暗黙の型変換 float y = sin(x); // y = (float)(sin((double)x)) という暗黙の型変換 などとすると、そのたびに型変換が発生します。 この分のオーバーヘッドでしょう。

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.2

一口にshort、int、long、float、doubleといっても何バイトを割り当てるかは それぞれの処理系(ハードとコンパイラー)の実態に合わせて決めることに成っています。 従って一概には言えません。 例えばintを標準的に扱うマシンで仮にshortを扱うとすれば前後に変換が入る分だけ 遅くなります。 どうしても気になるならそれぞれの実装(機種とコンパイラー)で ベンチマークテストをやってみるしかありません

回答No.1

処理系(コンパイラ)によって異なるし、それに微々たるものです。 まずアルゴリズムとデータ構造で速くしましょう。 それ以上のパフォーマンスを求めるなら、実測してその結果で判断しましょう。

amazontester
質問者

お礼

そうですね。やはり自分のコードを早くしないと・・

関連するQ&A

  • C言語でテーブル引きしたら速度が遅くなった

    プログラムに悩んでいるものです. とある画像処理のプログラムを組んでいるのですが,処理が遅くテーブル引きを組んでいます. この前もこの場を借りて質問しsqrt()のテーブル引きは実現したのですが,処理速度が遅くなってしまい原因が分からないので質問させていただきました. 前の質問URL:http://okwave.jp/qa/q7103550.html 前回から修正した現在のプログラムの一部を示します. ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー void filter(unsigned char* d, short *dx, short *dy, int w, int h) { ///// テーブル生成 ///// static int c_size = 0; // static 値を保持 static double c_sqrt[1020][1020]; if(c_size != 1020){ // 初回呼び出しのみ実行 c_size = 1020; for(int i=0; i<c_size; i++){ // 有りえるすべての値を生成 for(int j=0; j<c_size; j++){ c_sqrt[i][j] = sqrt( (double)(i*i + j*j) ); } } } ///// d = sqrt(dx^2 + dy^2) ///// for(int y = 1; y < h-1; ++y){ for(int x = 1; x < w-1; ++x){ double u = (double)dx[y*w+x]; double v = (double)dy[y*w+x]; if(u<0) u=-u; if(v<0) v=-v; int val = (int)c_sqrt[(int)u][(int)v] /4; if(val>255) val=255; d[y*w+x] = val; } } } ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー テーブル引きをしない場合(プログラム省略)はこの関数の処理時間が約9[ms]だったのに対し,上記のプログラムは約15[ms]となってしまいました. どういう風に修正すれば,テーブル引きの効果が出せるでしょうか? 長い文章を最後までお読みいただきありがとうございます. ご回答,よろしくお願い致します.

  • 【C言語】 型のサイズについて

    C言語の学習をしております初心者です。 型のサイズについてですが、int型のサイズは処理系に依存する、 ということをよく聞きますが、この「処理系」というのは そのアプリケーションを動作させるマシンに搭載されている"CPU"を 指しているのでしょうか? それとも"OS"を指しているのでしょうか?

  • C言語の課題なんですがわかりません

    population/2 、 population/7 、 deit_days+weight_gain 、 salary*3 を計算した結果を printf 関数で表示するプログラムを作成せよ。 population/2 は、 int 型、 population/7 は float 型、 diet_days+weight_gain は int 型、 salary*3 は float 型である。 population, deit_days, weight_gain 、 salaryはキーボードから入力するものとする。 分かる方は、教えてください

  • c言語 型変換について

    c言語 型変換について 下記のように文字コードは、unsigned int型('B')をunsigned char 型(str[1] ) 格下げする型変換する規則を教えてください。 *質問ソースプログラム: int main(void) { char str[4]; /* 文字列を格納する配列 */ str[0] = 'A'; /* 代入 */ str[1] = 'B'; /* 代入 */ ・・・・・・ printf("size B %u\n",(unsigned)sizeof('B')); printf("size str[1] %u\n",(unsigned)sizeof(str[1])); * 実行結果 size B 4 size str[1] 1

  • C/C++の型について

    Windows2000で、VC++6で型のサイズを調べると、以下のとおりでした。 int 4バイト long 4バイト long int 4バイト 環境はWindows2000, CPUはCeleron1200Mhzです。 環境やコンパイラによって型のサイズや呼び方も変わるのでしょうか? VisualBasic6用のDLLをVCで作成した記憶があるのですが、そのときは VB6のInteger型が2バイトだったので C(Ver7.0?????)側も2バイトだったと思います。 今VB6のInteger型にあわせる場合はC側ではshortでないとおかしくなるのでしょうか? 私はブランクがあり、そのあたりの事情がよくわかっていません。 あるサイトのページを見ると intが2バイトで、 long intは同じ4バイトで long long intという型もありました。VC6++では long long intは無いようです。 http://seclan.dll.jp/c99d/c99d05.htm VC2005++やGCCでは8バイトの型はあるのでしょうか?

  • 型変換??

    int RANDOM_FUNCTION( int n ) { return (int)( rand() / (float)RAND_MAX * n ); } について Q1.この関数は0からn-1までの乱数を作るそうなのですが,何故ですか? 0<=rand()<=RAND_MAX だから0からnまでの乱数ができるような気がするのですが. Q2.RAND_MAXではなく(float)RAND_MAXとキャストしてある意味は何ですか? Q3.srand((unsigned)time(NULL));と srand((unsigned int)time(NULL));では何か違いますか? Q4.  static int first = 0; if (first == 0){ srand((unsigned)time(NULL)); first = 1; } という処理でsrand((unsigned)time(NULL));は最初の一回だけ呼び出されるようになっているようですが,この部分を srand((unsigned)time(NULL)); というように毎回呼び出すようにするとどうなりますか? 一回呼び出すだけで乱数系列の初期値が呼び出される時に変化しているのですか? Q5.この関数とは関係ない質問ですが,例えば a:int型 b:int型 c:double型 d:float型 のとき d = a / b + c という演算は 1 a:int型,b:int型より(a / b)の結果はint型(小数になった場合は小数点以下切り捨て) 2 (a / b):int型,c:double型,int<doubleより (a / b + c)の結果はdouble型 3 d:float型,『=のあるときは左辺の型に合わせる』よりdはfloat型 というように型変換されているという解釈でいいのでしょうか??

  • C言語でsqrt(a^2+b^2)のテーブル引き

    プログラムに悩んでいるものです. とある画像処理のプログラムを組んでいるのですが,処理が遅くテーブル引きを組んでいます. 三角関数などはすんなりできたのですが,質題にもある通りsqrt(a^2+b^2)が実現できず,この場を借りて質問させていただきました. 以下にプログラムの一部を示します. ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー void filter(unsigned char* d, short *dx, short *dy, int w, int h) { ///// テーブル生成 ///// static int c_size = 0; // static 次の呼び出しでも値保持 static double *c_sqrt = NULL; // c_size = 255;              // u,v:0~255 c_sqrt = (double *)malloc(sizeof(double)*c_size*c_size); // 領域確保 for(int i=0; i<c_size; ++i){     // 有りえるすべての値を生成 for(int j=0; j<c_size; ++i){ c_sqrt[i*j] = sqrt( (double)(i*i + j*j) ); } } ///// d = sqrt(dx^2 + dy^2) ///// for(int y = 1; y < h-1; ++y){ for(int x = 1; x < w-1; ++x){ double u = (double)dx[y*w+x]; double v = (double)dy[y*w+x]; int val = (int)c_sqrt[ (int)(u*v) ] /4; if (val>255) val=255; d[y*w+x] = val; } } } ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 見てご察し頂ける(?)と思いますが,この関数は何回も呼び出すので,上のほうででテーブル引きしようとしてます. ただ明らかなプログラム経験不足のためかうまくいってません. 個人的にはc_sqrtを別途関数c_sqrt(u,v)にしたほうがよいのかと思ってます. どういうプログラム記述をすれば,このテーブル引きが実現できるでしょうか? ご回答,お力添え,よろしくお願い致します.

  • 型指定子についての教えてください。

    コンパイラはMicrosoft visual C&C++を使用しています。 (1)型指定子のfloat,doubleの大きい数値について。 計算をするとfloatは7桁までは正しくて、7桁より大きい桁はデタラメです。doubleは15桁までは正しくて、15桁より大きい桁はデタラメです。有効数字7桁,15桁とはこういうことでしょうか。 後、floatは有効数字7桁、doubleは有効数字15桁で本当に正しいのでしょうか。 (2)型指定子のfloat,doubleの小数点以下の数字について。 floatは10^-38まで、doubleは10^-308までの数字を扱えると参考書には書いてありますが、計算をしますと小数点以下6桁までは求まりますが、それ以下は求まりまりません。それ以下の数値はすべて0になります。なぜでしょうか。 (3)int,long intとdouble long doubleの違いについて。 intとlong intはともに-2147483648~2147483647までの範囲だと思います。またdoubleとlong doubleはともに有効数字15桁でした。何か違いがあるのでしょうか?

  • C言語 型変換について

    以下のように型変換すると a1 = 123.78、a2 = 123、b = 77、a3 = 78 となり、なぜb=77となってしまうのかわかりません。 詳しい方、すみませんが教えてください。よろしくお願いします。 float a1, a2, a3; int b; void main() { a1 = 123.78; a2 = (int)a1; b = (a1 - a2)*100; a3 = (a1 - a2)*100; printf("a1 = %3.3f, a2 = %3.3f, b = %3d, a3 = %3.3f" , a1, a2, b, a3); }

  • VC++6.0でC言語の基本データ型のビット長と範囲をしりたいです

    VC++6.0を使用しています。コマンドラインを使い勉強しているのですが、基本データ型のビット長と使える数の範囲を知りたいです。 たとえば、int型だと32ビットで-32767から32767の範囲の数を扱えるとかを知りたいです。コマンドライン上から調べることはできないのでしょうか? ネットでも書いてあるところがあるならいいのですが、できれば自分の手で調べる方法を見つけたいのです。 ちなみに char, unsigned char, int, unsigned int, short int, unsigned short int, long int unsigned long int, float, double, long doubleなどが知りたいです。 方法を知っている方教えてください。よろしくお願いします。