0

这个方法得到:

IEnumerable<object[]>- 其中每个数组都是固定大小的(它代表关系数据结构)。

DataEnumerable.Column[]- 一些元数据列,大多数情况下它们对所有行都具有相同的值。

预期结果:

每个“行”都应该为这些列中的每一列获取值(因此数据结构保持相关)。

    private IEnumerable<object[]> BindExtraColumns(IEnumerable<object[]> baseData, int dataSize, DataEnumerable.Column[] columnsToAdd)
    {
        int extraColumnsLength = columnsToAdd.Length;
        object[] row = new object[dataSize + extraColumnsLength];

        string columnName;
        int rowNumberColumnIndex = -1;

        for (int i = 0; i < extraColumnsLength; i++)
        {
            //Assign values that doesn't change between lines..
            // Assign rowNumberColumnIndex if row number column exists
        }

        //Assign values that change here, since we currently support only row number
        // i'ts not generic enough        
        if (rowNumberColumnIndex != -1)
        {
            int rowNumber = 1;

            foreach (var baseRow in baseData)
            {
                row[rowNumberColumnIndex] = rowNumber;

                Array.Copy(baseRow, 0, row, extraColumnsLength, dataSize);

                yield return row;

                rowNumber++;
            }
        }
        else
        {
            foreach (var baseRow in baseData)
            {
                Array.Copy(baseRow, 0, row, extraColumnsLength, dataSize);

                yield return row;
            }
        }
    }

可以从具有相对较大数据集的数百个线程调用此方法,因此这里的性能至关重要,我尝试创建尽可能少的新对象。

请注意 - 这是一个私有方法,仅由DataReader 使用,它读取每一行,并在读取下一行之前将其传递给另一个数组。

那么-在这里复制数组是否会以某种方式在这里进行优化,我应该(小心地)使用内存来提升这里的东西吗?

谢谢

4

1 回答 1

5

您的代码从根本上被破坏了。您每次都只是返回对同一个数组的引用,这意味着除非调用者立即使用每个项目中的数据,否则它实际上会丢失。例如,假设我使用:

List<object[]> rows = BindExtraColumns(data, size, toAdd).ToList();

然后,当我遍历行时​​,我会在每一行中找到相同的数据。这真的不是什么好的体验。

我认为为每次迭代创建一个新数组会更有意义是的,这是使用了很多额外的内存 - 但它并没有让调用者感到惊讶。

如果你真的不想这样做,我建议你改变方法,以便调用者必须传入一个Action<object[]>要在每一行上执行的,有记录的附带条件是,如果调用者隐藏对数组的引用,他们可能对结果感到惊讶。

您显然非常关心性能,但如果您的数据来自数据库,我希望数组创建/复制性能微不足道。您应该首先编写最简单(也是最可靠)的代码,然后对其进行基准测试以查看其性能是否足够好。除非你有证据表明你需要做出这个令人惊讶的设计选择,否则感觉你优化得太早了。

编辑:现在我们知道它是一种在一个特定地方使用的私有方法,我仍然会避免这种重用。它简直是脆弱的。我真的会改为Action<object[]>每次都传入一个或简单地将数据复制到一个新数组中。如果没有强有力的证据表明这是一个瓶颈,我当然不会保留当前的方法:正如我之前所说,我希望数据库通信更加重要。像这样在代码中留下定时炸弹很少能奏效。

如果你真的,真的想继续这样做,你应该非常强烈地记录它,并严重警告结果是非惯用的。

就您是否可以进行更多优化而言-嗯...一种替代方法是首先避免使用单个数组。您可以创建一个包含对两个数组(当前基行和固定数据)的引用的类,并公开一个索引器,该索引器根据请求的索引从一个数组或另一个数组返回值。我们不知道您对数据做了什么(“将其传递给另一个数组”实际上并没有任何意义)所以我们不知道这是否可行,但它会很有效并且可以在没有奇怪的情况下实现行为。

于 2013-09-04T08:15:37.720 回答