最快的算法,用于创建已知大小的数组

时间:2012-07-23 08:36:30

标签: c# algorithm

我需要创建一个布尔值数组,其范围可以是100,000s甚至数百万条。它还需要超快,因此每次迭代的每毫秒都很重要。

在开始循环时,我已经知道数组中将有多少条目。问题是,预先创建一个bool数组并通过索引填写值会更快(这是随机访问 - 可能会很慢吗?),或者我应该创建一个List<bool>,继续添加条目到列表,最后返回.ToArray()

换句话说:

选项1

var array = new bool[size];
for (var n=0; n<size; n++)
  array[n] = GetValue(n);
return array;

选项2

var list = new List<bool>();
for (var n=0; n<size; n++)
  list.Add(GetValue(n));
return list.ToArray();

或许还有第三种方式甚至更快?

4 个答案:

答案 0 :(得分:5)

使用System.Collections.BitArray,不要担心速度。

上面你的建议只会浪费你的记忆力。这样可以优化速度和大小,并且可以很好地打包bool值(每个字节8个,如众神所预期的那样:)。

回复以下评论:如果您使用BitArray,一切都将为零。仅设置您拥有GetValue == true

的位

答案 1 :(得分:2)

与第一个一起去。它可能是唯一的原因。 “慢”是指它是否保持从处理器缓存外部分页数据。

该列表将具有完全相同的问题,除了它还需要执行多个内存分配和副本。

答案 2 :(得分:2)

以下代码似乎显示(至少对我来说)本页讨论的方法,使用循环对bool[]的简单分配是最快的。

代码似乎也告诉我,除非GetValue(n)在计算上是微不足道的,否则分配字节的开销不是我希望优化的过程的一部分。

希望这在某种程度上有所帮助。

编辑:添加了运行结果(在我的机器上)

--  187ms    BitArray
--  171ms    List<bool>().ToArray 
--  168ms    bool[] set only if true
--  130ms    bool[] always set
--11460ms    bool[] always set with 'complex' GetValue()

class Program
{
    static void Main(string[] args)
    {
        BitArray bitArray = new BitArray(10000000);
        bool[] boolArray = new bool[10000000];

        Stopwatch sw1 = new Stopwatch();

        sw1.Start();

        for (int i = 0; i < 10000000; i++)
        {
            bitArray[i] = GetMod2(i);
        }

        Console.WriteLine(sw1.ElapsedMilliseconds);

        sw1.Restart();

        var list = new List<bool>();
        for (int i = 0; i < 10000000; i++)
            list.Add(GetMod2(i));
        var boolArray2 = list.ToArray();

        Console.WriteLine(sw1.ElapsedMilliseconds);

        sw1.Restart();

        for (int i = 0; i < 10000000; i++)
        {
            bool nextVal = GetMod2(i);

            if (nextVal)
                bitArray[i] = true;
        }

        Console.WriteLine(sw1.ElapsedMilliseconds);

        sw1.Restart();


        for (int i = 0; i < 10000000; i++)
        {
            boolArray[i] = GetMod2(i);
        }

        Console.WriteLine(sw1.ElapsedMilliseconds);

        sw1.Restart();

        for (int i = 0; i < 10000000; i++)
        {
            boolArray[i] = GetRand(i);
        }

        Console.WriteLine(sw1.ElapsedMilliseconds);

        Console.ReadLine();
    }

    static bool GetMod2(int i)
    {
        return (i % 2) == 1;
    }

    static bool GetRand(int i)
    {
        return new Random().Next(2) == 1;
    }
}

答案 3 :(得分:0)

现在这是一件有趣的旧事。在@paul的启发下,我自己运行了10,000,000个布尔值的基准测试。考虑到对这个问题的评论中的讨论,结果(以毫秒为单位)非常令人惊讶:

  

BitArray:517

     

BitArray + CopyTo(数组):536

     

List + ToArray():455

     

bool array:483

这是什么样的书!尽管List<Bool>每次都插入一条新记录,而bool[]BitArray在每条记录上都被初始化为false,而我只更新了它们价值应该是trueList<bool>一致,一致,甚至包括.ToArray()电话。

另一种情况是实际应用比教科书知识更好,似乎......:)