有两种方法来零出的整数/ float数组:
memset(array, 0, sizeof(int)*arraysize);
要么:
for (int i=0; i <arraysize; ++i)
array[i]=0;
显然,memset的是大快arraysize
。 不过,在什么点是memset的开销实际上比for循环开销更大? 例如,对于大小为5的阵列 - 这将是最好的? 第一个,第二个,或者甚至未推出的版本:
array[0] = 0;
array[1] = 0;
array[2] = 0;
array[3] = 0;
array[4] = 0;
在所有的可能性,memset的()将你的编译器内联(大多数编译器把它当作一个“内在”,这基本上意味着它内联,可能除了在最低优化或除非明确禁用)。
例如,这里有一些从GCC 4.3发布说明 :
代码生成块移动(的memcpy
)和块集( memset
)被重写。 现在GCC可以挑选基于所述块的大小被复制和CPU进行优化的最佳算法(循环,展开的循环,与代表前缀或库调用指令)。 一个新的选项-minline-stringops-dynamically
增加了。 随着未知大小的这个选项字符串操作的扩展,使得小的块由行代码复制,而对于大块用于库调用。 这导致比更快的代码-minline-all-stringops
当库的实现能够使用缓存层次结构的提示。 选择特定算法启发式可以通过覆盖-mstringop-strategy
。 新近还memset
从0被内联不同的值。
这可能是可能的编译器做你给替代的例子类似的东西,但我敢打赌那是不太可能。
而且它的grep
-able,更显而易见,一目了然什么意图是开机(不环路是特别困难神交其一)。
正如迈克尔已经指出,gcc和我猜大多数其他编译器优化这已经非常好。 例如GCC原来这
char arr[5];
memset(arr, 0, sizeof arr);
成
movl $0x0, <arr+0x0>
movb $0x0, <arr+0x4>
它没有得到任何比这更好的?
有没有回答这个问题没有测量方式。 这将完全取决于编译器,CPU和运行时库实现。
memset的()可以是“代码味道”的位,因为它可以容易出现缓冲区溢出,参数逆转和具有仅清除“逐字节”不幸能力。 但是这是一个安全的赌注,这将是在所有的,但极端情况下“最快”。
我倾向于使用宏来包装是为了避免一些问题:
#define CLEAR(s) memset(&(s), 0, sizeof(s))
此回避了大小计算并除去交换的长度和vlaue参数的问题。
总之,使用memset的()“下的发动机罩”。 写你打算什么,并让有关的优化编译器担心。 大多数是在它令人难以置信的好。
考虑到这个代码本身evrything已经被告知。 但是,如果你在它的计划,该计划的我不知道什么考虑,别的东西可以做到的。 例如,如果这个代码将每一段时间执行清除数组,你可以运行一个线程,不断地分配分配给全局变量零个元素的新数组,你的代码,当需要阵列被清除,仅指向。
这是第三个选项。 当然,如果您打算与至少两个核心的处理器上运行的代码,这是有道理的。 还必须对代码进行运行不止一次看到它的好处。 对于只有一次性运行,你可以声明零填充数组,然后在需要时指向它。
希望这可以帮助别人
文章来源: clearing a small integer array: memset vs. for loop