C# 从数组中采样

C# 从数组中采样,c#,C#,我有一个包含1M个浮点数的浮点数数组 我想做采样:对于每4个浮点数,我只想取1个。因此,我正在这样做: for(int i = 0; i< floatArray.Length; i++) { if(i % 4 == 0) { resultFloat.Add(floatArray[i]) } } for(int i=0;i>2]; for(int i=0;i>2]; for(int i=0;i

我有一个包含1M个浮点数的浮点数数组

我想做采样:对于每4个浮点数,我只想取1个。因此,我正在这样做:

for(int i = 0; i< floatArray.Length; i++) {
    if(i % 4 == 0) {
         resultFloat.Add(floatArray[i])
    }
}
for(int i=0;i

这很好,但是运行所有元素需要很多时间,是否有其他方法可以获得更好的结果(如果有)

每次迭代只需将循环增加4,而不是1:

for(int i = 0; i< floatArray.Length; i+=4)
{
    resultFloat.Add(floatArray[i]);
}
for(int i=0;i
每次迭代只需将循环增加4,而不是1:

for(int i = 0; i< floatArray.Length; i+=4)
{
    resultFloat.Add(floatArray[i]);
}
for(int i=0;i
我发现有两个因素可能会降低性能

  • 由于已经向您提供,您应该将步骤设置为4:

    for (int i = 0; i < floatArray.Length; i += 4)
    {
        resultFloat.Add(floatArray[i]);
    }
    

  • 我可以看到两个可能会降低性能的因素

  • 由于已经向您提供,您应该将步骤设置为4:

    for (int i = 0; i < floatArray.Length; i += 4)
    {
        resultFloat.Add(floatArray[i]);
    }
    
  • List List=新列表();
    增加第(1)款;
    增加(2);
    增加(3);
    增加(4);
    增加(5);
    增加(6);
    增加(7);
    增加(8);
    增加(9);
    增加(10);
    增加(11);
    增加(12);
    增加(13);
    增加(14);
    增加(15);
    增加(16);
    var sampleData=list.Where((x,i)=>(i+1)%(4)==0.ToList();
    
    列表=新列表();
    增加第(1)款;
    增加(2);
    增加(3);
    增加(4);
    增加(5);
    增加(6);
    增加(7);
    增加(8);
    增加(9);
    增加(10);
    增加(11);
    增加(12);
    增加(13);
    增加(14);
    增加(15);
    增加(16);
    var sampleData=list.Where((x,i)=>(i+1)%(4)==0.ToList();
    
    如果您确实存在性能问题,那么最好不要使用动态容器,而是使用静态大小的数组

    float[] resultFloat = new float[(floatArray.Length + 3) >> 2];
    for(int i = 0; i < resultFloat.Length; i++)
        resultFloat[i] = floatArray[i << 2];
    
    float[]resultFloat=newfloat[(floatArray.Length+3)>>2];
    for(int i=0;iresultFloat[i]=floatArray[i如果您在性能方面确实存在问题,那么最好不要使用动态容器来处理结果,而是使用静态大小的数组

    float[] resultFloat = new float[(floatArray.Length + 3) >> 2];
    for(int i = 0; i < resultFloat.Length; i++)
        resultFloat[i] = floatArray[i << 2];
    
    float[]resultFloat=newfloat[(floatArray.Length+3)>>2];
    for(int i=0;iresultFloat[i]=floatArray[i只需添加另一个选项,如果您希望这是最快的,请使用
    Parallel.For
    而不是普通的For循环

    int resultLength = (floatArray.Length + 3) / 4;
    var resultFloat = new float[resultLength];
    
    Parallel.For(0, resultLength, i =>
    {
        resultFloat[i] = floatArray[i * 4];
    });
    

    只需添加另一个选项,如果您希望这是最快的,请使用
    Parallel.For
    而不是普通的For循环

    int resultLength = (floatArray.Length + 3) / 4;
    var resultFloat = new float[resultLength];
    
    Parallel.For(0, resultLength, i =>
    {
        resultFloat[i] = floatArray[i * 4];
    });
    


    for(int i=0;i
    我曾想过使用linq处理对象,但答案很简单,工作更聪明,我想我很笨,但有没有机会用linq使它更快?并行
    for
    可能更好。在
    resultFloat
    上保留足够的容量也可能会有所帮助。
    resultFloat=新列表((floatArray.Length+3)/4);
    或者甚至可以切换到普通数组而不是
    列表。这里到底有什么慢?是通过数组循环还是创建一个全新的数组?您真的需要创建一个新列表吗?
    for(int i=0;i
    我曾想过使用linq处理对象,但答案很简单,工作更聪明,我想我很笨,但有没有机会用linq使它更快?并行
    for
    可能更好。在
    resultFloat
    上保留足够的容量也可能会有所帮助。
    resultFloat=新列表((floatArray.Length+3)/4);
    或者甚至可以切换到普通数组而不是
    列表。这里到底有什么慢?是通过数组循环还是创建一个全新的数组?您真的需要创建一个新的列表吗?这可能会抛出超出范围的异常,例如,如果
    floatArray.Length
    为3,则可以保留一个数组而不是一个list但设置初始大小
    var resultFloat=new List(m);
    它将在幕后执行相同的操作,但您仍然可以调用add。这可能会抛出超出范围的异常,例如,如果
    floatArray.Length
    为3,则可以保留一个列表而不是数组,但可以设置初始大小
    var resultFloat=new List(m)
    它会在幕后做同样的事情,但你仍然可以调用add。这在所有性能上会有什么变化?为什么还要演示如何将项目添加到
    列表
    ?代码只是我创建的一个快速示例。主要部分显然是最终linq。你可以忽略列表添加。不要认为这会产生太多问题如果粘贴在此处,则会出现问题。理想情况下,没有比循环更多的选项。Linq将使其成为一个单行程序。因此,请解释Linq将如何比for循环更快。提示:不会。这在所有性能方面都会有什么变化?为什么还要演示如何将项添加到
    列表
    ?代码只是我创建的一个快速示例。主要部分显然是最后一个linq。你可以忽略列表添加。如果粘贴到这里,不要认为这会产生太多问题。理想情况下,没有比循环更多的选项。linq只会使它成为一个一行。因此,请解释linq将如何比for循环快。提示:不会。为什么你要发布另一个答案,而不是编辑你已经回答的内容?还有,你可以可能需要解释这是如何工作的。如果
    floatArray.Length%4!=0
    @CamiloTerevinto,则会出现一个逐个错误,因为这是一个根本不同的答案,而不仅仅是一种改进,发布一个新的(并删除旧的)是有道理的。我支持这两个答案。@ThomasHilbert你应该将你的代码复制到一个.NET小提琴中,并了解你的另一个答案实际上比OP当前的答案慢得多。为什么你要发布另一个答案而不是编辑你已经回答的答案?另外,你可能想解释一下这是如何工作的。如果 floatArray.Length%4!=0
    @CamiloTerevinto,因为它是