【问题标题】:Redim boolean Array vs enumerate and setRedim布尔数组与枚举和设置
【发布时间】:2010-07-23 07:28:24
【问题描述】:

如果您想重置一个布尔值数组,那么重新设置数组或枚举并重置值更快?

我已经运行了一些测试,它们似乎表明 redim 更快,但我不相信这不是我运行测试的结果。

我的测试似乎表明 redim 的速度几乎是原来的两倍。

那么有没有人愿意评论一下哪个更快,为什么?此外,您是否希望跨不同语言获得相同的结果?

枚举测试:

Dim booleanArray(200) As Boolean

        Dim startTime As Date = Date.Now

        For i As Integer = 0 To 9999999
            For l As Integer = 0 To 200
                booleanArray(l) = True
            Next
        Next

        Dim endTime As Date = Date.Now

        Dim timeTaken As TimeSpan = endTime - startTime

Redim 测试:

Dim booleanArray(200) As Boolean

        Dim startTime As Date = Date.Now

        For i As Integer = 0 To 9999999
            ReDim booleanArray(200)
        Next

        Dim endTime As Date = Date.Now

        Dim timeTaken As TimeSpan = endTime - startTime

【问题讨论】:

  • 因为这与 c# 和 vb 一样多,所以我的示例恰好是 vb
  • @OP FYI - ALLOT 应该读很多
  • 这是两种不同的算法。你在比较苹果和橘子。
  • @Winston Smith 哈哈,我不知道这是 GrammarOverflow.com :-p

标签: vb.net arrays optimization


【解决方案1】:

这表明分配新数组很快。当有大量可用内存时,这是可以预料的 - 基本上它是增加一个指针和一点点的家务。

但是,请注意,这将创建一个所有元素为 False 而不是 True 的新数组。

更合适的测试可能是在现有数组上调用Array.Clear,在第一种情况下,这将很快清除内容。

请注意,您的第二种形式会产生更多垃圾 - 在这种情况下,它将始终留在 gen0 中并且很容易被收集,但在具有更实际内存使用的实际应用程序中,您最终可能会导致垃圾收集性能问题创建新数组而不是清除旧数组。

这里有一个 C# 中的快速基准测试,用于测试三种策略:

using System;
using System.Diagnostics;

public class Test
{
    const int Iterations = 100000000;

    static void Main()
    {
        TestStrategy(Clear);
        TestStrategy(ManualWipe);
        TestStrategy(CreateNew);
    }

    static void TestStrategy(Func<bool[], bool[]> strategy)
    {
        bool[] array = new bool[200];
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            array = strategy(array);
        }
        sw.Stop();
        Console.WriteLine("{0}: {1}ms", strategy.Method.Name,
                          (long) sw.ElapsedMilliseconds);
    }

    static bool[] Clear(bool[] original)
    {
        Array.Clear(original, 0, original.Length);
        return original;
    }

    static bool[] ManualWipe(bool[] original)
    {
        for (int i = 0; i < original.Length; i++)
        {
            original[i] = false;
        }
        return original;
    }

    static bool[] CreateNew(bool[] original)
    {
        return new bool[original.Length];
    }
}

结果:

Clear: 4910ms
ManualWipe: 19185ms
CreateNew: 2802ms

但是,这仍然只是使用第 0 代 - 我个人希望 Clear 对整体应用程序性能更好。请注意,如果任何其他代码引用了原始数组,它们的行为会有所不同——“创建新”策略 (ReDim) 根本不会更改现有数组。

【讨论】:

  • ReDim 不保留现有内容... Redim Preserve 确实... 或者您的意思是内容保留在内存中的某个位置?
  • "如果不指定PreserveReDim 会将新数组的元素初始化为其数据类型的默认值。" msdn.microsoft.com/en-us/library/w8k3cys2(VS.80).aspx
  • 谢谢乔恩,如果没有您清晰详细的回答,我们不知道该怎么办... :-)
  • @Maxim:你的意思是之后我弄错了 ReDim 行为? :)
【解决方案2】:

这些测试没有可比性。
第一个测试将每个元素设置为 true,而 Redim 没有这样做。

Redim 帮助您增加/减少边界并清理内容(并将其设置为默认值)。 例如Redim 将帮助将 boolean 数组的内容设置为 false。

您是否希望Redim 将所有元素设置为true

Dim booleanArray(200) As Boolean

For l As Integer = 0 To 200
   booleanArray(l) = True
Next

Redim booleanArray(200)

这会将booleanArray 的每个元素的内容重置为false

如果您想保留内容并增加大小 - Redim Preserve booleanArray(300)(而不是 Redim booleanArray(200))。这会将前 200 个元素保留为 true,新的 100 个元素将具有默认值 (false)。

【讨论】:

    【解决方案3】:

    我已经在 C# 语言 3.5 中对此进行了测试

    枚举测试所用时间:00:00:06.2656 Redim 测试所用时间:00:00:00.0625000

    正如您所见,Redim 速度要快得多,因为您无需为其设置任何值。

    【讨论】:

      【解决方案4】:

      我希望 ReDim 更快,因为您没有为数组的每个项目分配值。

      微基准测试显示正常。

      【讨论】:

      • 它应该清理数组内容。 Redim Preserve 将保留内容(根据我对 VB6 的理解)。
      • @shahkalpesh - vb.net 不是 vb6,但 redim 语法是一样的。
      • 当然。而且它们不会改变语句的含义。
      猜你喜欢
      • 1970-01-01
      • 2011-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-23
      • 2011-10-02
      相关资源
      最近更新 更多