1

私は自分のプログラムのパフォーマンスを改善しようとしています (ARC プラットフォームで実行され、arc-gcc でコンパイルされています。そうは言っても、プラットフォーム固有の回答は期待していません)。

次のどの方法がより最適で、その理由を知りたいです。

typedef struct _MY_STRUCT
{
    int my_height;
    int my_weight;
    char my_data_buffer[1024];
}MY_STRUCT;

int some_function(MY_STRUCT *px_my_struct)
{
    /*Many operations with the structure members done here*/
    return 0;
}

void poorly_performing_function_method_1()
{
    while(1)
    {
        MY_STRUCT x_struct_instance = {0}; /*x_struct_instance is automatic variable under WHILE LOOP SCOPE*/
        x_struct_instance.my_height = rand();
        x_struct_instance.my_weight = rand();
        if(x_struct_instance.my_weight > 100)
        {
            memcpy(&(x_struct_instance.my_data_buffer),"this is just an example string, there could be some binary data here.",sizeof(x_struct_instance.my_data_buffer));
        }
        some_function(&x_struct_instance);

        /******************************************************/
        /* No need for memset as it is initialized before use.*/
        /* memset(&x_struct_instance,0,sizeof(x_struct_instance));*/
        /******************************************************/
    }
}

void poorly_performing_function_method_2()
{
    MY_STRUCT x_struct_instance = {0}; /*x_struct_instance is automatic variable under FUNCTION SCOPE*/
    while(1)
    {
        x_struct_instance.my_height = rand();
        x_struct_instance.my_weight = rand();
        if(x_struct_instance.my_weight > 100)
        {
            memcpy(&(x_struct_instance.my_data_buffer),"this is just an example string, there could be some binary data here.",sizeof(x_struct_instance.my_data_buffer));
        }
        some_function(&x_struct_instance);
        memset(&x_struct_instance,0,sizeof(x_struct_instance));
    }
}

上記のコードでは、poorly_performing_function_method_1()パフォーマンスが向上しますか、それともpoorly_performing_function_method_2()パフォーマンスが向上しますか? なんで?

考えるべきことはほとんどありません..

  • 方法 1 では、構造体メモリの割り当て解除、再割り当てでオーバーヘッドが増える可能性がありますか?
  • 方法 1 では、初期化中に最適化が行われていますか? calloc (楽観的なメモリ割り当てとゼロで満たされたページへのメモリの割り当て) のように?

私の質問は、このコードをより最適にする方法についてではなく、どの方法がより最適であるかについての質問であることを明確にしたいと思います。このコードは単なる例です。

上記のコードをより最適化することについて、@Skizz は正しい答えを出しました。

4

1 に答える 1

3

一般的に、何かをしないことは、何かをするよりも速くなります。

コードでは、構造体をクリアしてから、データで初期化しています。あなたは2つのメモリ書き込みを行っています.2番目は最初のものを上書きするだけです.

これを試して:-

void function_to_try()
{
  MY_STRUCT x_struct_instance;
  while(1)
  {
    x_struct_instance.my_height = rand();
    x_struct_instance.my_weight = rand();
    x_struct_instance.my_name[0]='\0';
    if(x_struct_instance.my_weight > 100)
    {
        strlcpy(&(x_struct_instance.my_name),"Fatty",sizeof(x_struct_instance.my_name));
    }
    some_function(&x_struct_instance);
  }
}

アップデート

より最適な質問に答えるために、方法#1をお勧めしますが、それはおそらく限界であり、コンパイラやその他の要因に依存しています。私の推論は、割り当て/割り当て解除が行われておらず、データがスタック上にあり、コンパイラによって作成された関数プリアンブルが、サイズを変更する必要がないように関数に十分な大きさのスタック フレームを割り当てるということです。いずれにせよ、スタックへの割り当てはスタック ポインタを移動するだけなので、大きなオーバーヘッドにはなりません。

また、memset はメモリを設定するための汎用的な方法であり、アライメントされていないメモリなどのエッジ条件に対処する追加のロジックが含まれている場合があります。コンパイラは、汎用アルゴリズムよりもインテリジェントにイニシャライザを実装できます (少なくとも、そうすることが望まれます)。

于 2013-10-01T15:27:44.553 に答える