【问题标题】:How do I initialize arrays more efficiently than a for loop? c++如何比 for 循环更有效地初始化数组? C++
【发布时间】:2021-01-12 05:40:32
【问题描述】:

目前,我正在通过创建 for 循环并设置 arr[I] = 0 来初始化数组。还有其他更有效的方法吗?

Student::Student(){
    
    name = "John";
    for(int i = 0; i<sizeof(id);++i)
    {
        id[i] = '0';
    }
    for(int i = 0; i<sizeof(testScore);++i)
    {
        testScore[i] = 0;
    }
    avgScore = 100;
    grade = 'A';
    
}

【问题讨论】:

  • 嗨!这是什么编程语言?请将其添加到标签中。
  • 对不起,是 cpp。
  • memset, calloc, ...
  • 你知道std::fill吗?或者使用memset 可能更有效。
  • 别打扰了。这是一个微优化。打印出汇编语言。提高优化级别,然后打印出汇编语言。为所有级别的优化执行此操作。

标签: c++ arrays initialization


【解决方案1】:

循环展开

这是一个循环展开的例子:

const int capacity = sizeof(id) / sizeof(id[0]);
const int fill_value = 0; // hopefully compiler assigns to a register.
int i = 0;
if (capacity & 3 == 0)
{  
    for (i = 0; i < capacity; i += 4)
    {
        id[i + 0] = fill_value;
        id[i + 1] = fill_value;
        id[i + 2] = fill_value;
        id[i + 3] = fill_value;
    }
}
// initialize remaining slots
for (; i < capacity; ++i)
{
    id[i] = 0;
}

在循环中使用fill_value 变量而不是常量是建议编译器将fill_value 放入寄存器。在许多处理器中,将寄存器写入内存比将常量写入内存或将常量加载到寄存器然后写入内存(在循环期间)更有效。

展开循环的想法是在跳转或分支指令之前连续执行更多数据指令。处理器不喜欢分支指令。分支指令导致处理器决定是否重新加载指令缓存;这占用了可用于执行数据指令的时间。展开的循环执行的比较也比原始循环少。同样,比较指令占用执行数据指令的时间。

无循环

目标是尽量减少分支和比较。
如果您的数组很小(根据您的定义),您可能希望在没有循环的情况下分配插槽:

int * p = &id[0];
const int fill_value = 0;
*p++ = fill_value;  *p++ = fill_value; *p++ = fill_value; *p++ = fill_value;  
*p++ = fill_value;  *p++ = fill_value; *p++ = fill_value; *p++ = fill_value;  
*p++ = fill_value;  *p++ = fill_value; *p++ = fill_value; *p++ = fill_value;  
*p++ = fill_value;  *p++ = fill_value; *p++ = fill_value; *p++ = fill_value;  
*p++ = fill_value;  *p++ = fill_value; *p++ = fill_value; *p++ = fill_value;  

增加指针和延迟的操作仍然比让处理器比较值或更改程序计数器(分支)更快。

【讨论】:

    【解决方案2】:

    你可以试试Zero initialization

    示例:

        int arr1[12] = {}; // values: 000000000000
        std::array<int, 5> arr2 = {}; // values: 00000
    

    这样您可以跳过 for 循环并获得更简洁的代码。

    【讨论】:

    • 更有效的解决方案是在构造时不初始化数组;在像std::cin 这样的输入过程中填写数组。零初始化可能最终会重复写入数组。
    猜你喜欢
    • 1970-01-01
    • 2014-05-24
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    相关资源
    最近更新 更多