本文通过对每个周期的多个项目进行迭代,同时相应地调整循环计数器来演示循环展开的优点。
大多数开发人员将遍历数组元素并执行数学运算,如以下代码片段所示。
for (int i = 0; i < array.Length; i++)
{
array[i] = i * 2;
}
尽管上面的代码片段非常简洁明了,但由于循环控制结构,它会产生成本。
请在下面找到上一个代码片段的重构版本
int len = array.Length;
for (int i = 0; i < len; i += 4)
{
array[i] = i * 2;
if (i + 1 < len) array[i + 1] = (i + 1) * 2;
if (i + 2 < len) array[i + 2] = (i + 2) * 2;
if (i + 3 < len) array[i + 3] = (i + 3) * 2;
}
通过重构代码,现在我们已将循环频率降低到 4,从而加快了执行速度。
除此之外,它还会减少
创建另一个名为的类,并添加以下代码片段LoopUnrolling
public static class LoopUnrolling
{
public static void BadWay() {
const int size = 1024;
int[] numbers = new int[size];
// Traditional loop
var watch = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < numbers.Length; i++)
{
numbers[i] = i * 2;
}
watch.Stop();
Console.WriteLine($"Traditional loop time: {watch.ElapsedTicks} ticks");
}
public static void GoodWay()
{
const int size = 1024;
int[] numbers = new int[size];
int len = numbers.Length;
var watch = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < len; i += 4)
{
numbers[i] = i * 2;
if (i + 1 < len) numbers[i + 1] = (i + 1) * 2;
if (i + 2 < len) numbers[i + 2] = (i + 2) * 2;
if (i + 3 < len) numbers[i + 3] = (i + 3) * 2;
}
watch.Stop();
Console.WriteLine($"Unrolled loop time: {watch.ElapsedTicks} ticks");
}
}
#region Day 26: Loop Unrolling
static string ExecuteDay26()
{
LoopUnrolling.BadWay();
LoopUnrolling.GoodWay();
return "Executed Day 26 successfully..!!";
}
#endregion
Traditional loop time: 20 ticks
Unrolled loop time: 12 ticks
正如输出所示,循环展开比传统的循环方法花费的时间要少得多。
源代码获取:公众号回复消息【code:89205
】