パフォーマンスの問題は「テクノロジー」だけでは解決できないことが多く、アーキテクチャ、テスト、前提条件などの総合的な問題となります。ただし、エンジニアの場合は、小さなことから始めて、いくつかの「明白な」小さな問題を解決する必要があります。そうしないと、小さなことが積み重なると大きなことになり、何千マイルも離れたダムがアリの巣となって崩壊してしまいます。
なぜ C++ のパフォーマンスは常に C よりも劣るのですか (http://benchmarksgame.alioth.debian.org/u32/performance.php?test=binarytrees などの Web サイトから最新のテスト結果を参照してください)。これには 3 つの理由があると思います:
1) テストに使用される C++ コンパイラーは最新の最適化テクノロジーを使用していません
2) C++ の付加価値はテストでは考慮されません
3) C++ アプリケーション レベルの「微妙さ」 (C++ に関する私の他のブログを参照してください) は、一般のプログラマが「教科書的なユースケース」を選択するのを妨げることが多く、その結果、アプリケーション レベルでいくつかの副作用が排除されません。
10 年以上前、私が Microsoft で開発していたとき、初期の C++ コンパイラー (当時は Microsoft VC++ アーキテクト) の作者である Stan Lippman に、チームの C++ パフォーマンスに関する一連の問題について相談したことを思い出します。では、重要な場所でインラインや RVO などのテクノロジーを使用し、パフォーマンスの問題を完全に解決しましたが、VC++ でいくつかの重大なエラーも見つかりました。 C++ のパフォーマンスの問題のほとんどは C++ の浅い理解にあり、そのほとんどは解決するのが難しいものではないことを私は認識しています。
例を使用して、微妙な詳細がプログラムのパフォーマンスにどのような影響を与えるかを比較して見てみましょう。
構造体intPair
{
int ip1;
int ip2;
intPair(int i1, int i2) : ip1(i1), ip2(i2) {}
intPair(int i1) : ip1(i1), ip2(i1) {}
};
//合計の計算 (値セマンティックを使用)
Int
Sum1(intPair p)
{return p.ip1 + p.ip2;
}
// 合計の計算 (参照セマンティックを使用)
int
Sum2(intPair &p)
{return p.ip1 + p.ip2;
}
// 合計の計算 (const ref セマンティックを使用)
Int
Sum3(const intPair& p)
{return p.ip1 + p.ip2;
}
上記の単純な
struct には 3 つの Sum 関数があり、これらはまったく同じことを行いますが、パフォーマンスは同じですか?テストには次のプログラムを使用します:
double Sum(int t, int ループ){
名前空間 std を使用します。
if (t ==
1)
{_ x
int x =0;
for(int i = 0; i
D 戻り値 Double (END -Begin) / CLOCKS_PER_SEC } else if (t == ) { Clock_t begin = Clock(); int x =0; intPair p(1,2); for(int i = 0; i { x += Sum1(p); } Clock_t end = Clock(); return double(end - begin) / CLOCKS_PER_SEC; } else if (t == 3) { Clock_t begin = Clock(); int x =0; intPair p(1,2); for(int i = 0; i { x += Sum2(p); } Clock_t end = Clock(); return double(end - begin) / CLOCKS_PER_SEC; } else if (t == 4) { Clock_t begin = Clock(); int x =0; intPair p(1,2); for(int i = 0; i { x += Sum3(p); } Clock_t end = Clock(); return double(end - begin) / CLOCKS_PER_SEC; } else if (t == 5) { Clock_t begin = Clock(); int x =0; for(int i = 0; i { x += Sum3(10); } Clock_t end = Clock(); return double(end - begin) / CLOCKS_PER_SEC; } 0を返す; } 私たちは 5 つのパターンを使用し、Sum1 と Sum3 には 2 つの調整方法を使用し、Sum2 には 1 つの調整方法を使用しました。
VisualStidio 2010中测试、結果是:
心のある論者は見ません、
3)例 2 では、関数の使用前に独自に生成されたコピー コンストラクターが使用されていますが、intPair オブジェクトが非常に小さいため、影響はほとんど確認されていない可能性があります。
4) 例 3 の性能は安定していますが、生成された命令比は例 2 よりも 2 本多く、「間接」方式が使用されています。 Intel の L1、L2 が関係しています。
5) 例 4 と例 3 はまったく同様に生成コードを生成します。const は試行時のみであり、生成される生成コードは const の有無とは無関係です。
b) 暗黙的な変換 2014-6-20 Seattle プログラムを書くのを手伝う時間はありません。アイデアを与えるだけで済みます。まず、3 種類の並べ替えに関する例をコピーして 3 つの関数に記述します。各関数では、システム時間が最初と最後に一度取得され、最後にオーバーヘッドを取得するために減算されます オンラインプログラムを修正して統合しました、見てください
。
#include
#include
#include
#define M 50
#define MAX 100000;
typedef struct
{
int Weight;//ノードの重み
intparent,lchild,rchild;
}HTNODE,*HUFFMANTREE;
typedef char** HUFFMANCODE;//ハフマンコーディングテーブルを格納する配列を動的に割り当てる
typedef struct
{
int key; /*keyword*/
}RecordNode; /*並べ替えノードの種類*/
typedef struct
{
RecordNode *record;
int n; /*並べ替えオブジェクトのサイズ*/
}ソート対象の配列
HUFFMANTREE huffmantree(int n,int Weight[])//ハフマンツリーの構築
{
int m1,m2,k;
int i,j,x1, x2;
HUFFMANTREE ht;
ht=( HUFFMANTREE)malloc((2*n)*sizeof(HTNODE));
for(i=1;i{
ht[i].parent=ht[i].lchild=ht[i].rchild=0;
if(iht [i].weight=weight[i] ;
else
ht[i].weight=0;
}
for(i=1;i
m1 =m2=MAX;
x1=x2=0;
for(j=1;j{
if((ht[j] .weight
m2=m1;
x2=x1;
m1=ht[j].weight;
x1=j;
}
else if ((ht[j].weight
m2=ht[j].weight;
x2=j;
}
}
k=n+ i;
ht[x1].parent=ht[ x2].parent=k;
ht[k].weight=m1+m2;
ht[k].lchild=x1;
ht[k].rchild=x2 ;
}
return ht;
}
void huffmancoding(int n,HUFFMANCODE hc,HUFFMANTREE ht,char str[])
{
int i,start,child,father;
char *cd;
hc=(HUFFMANCODE )malloc((n+1)*sizeof(char) *));//n 文字エンコーディングの先頭ポインターを割り当てます
cd=(char*)malloc(n*sizeof(char));//エンコーディング スペースを見つける作業を割り当てます
cd[n-1]=' \0';//エンコーディング ターミネータ
f...テキストの残りの部分>>