【问题标题】:Fastest way in C# to read block of bytes from file and converting to float[]C# 中从文件中读取字节块并转换为 float[] 的最快方法
【发布时间】:2010-06-04 15:11:15
【问题描述】:

我需要一种在 C# 语言中的快速方法,将编码一个 2 字节的短 (int16) 值的字节数组尽快转换/转换为浮点表示。性能瓶颈是方法:

samples[sample] = (float)binraryReader.readInt16();

(大量的 IO 调用,所以我不得不转换为块读取)

基本上我有一个包含短类型声音样本块 (~100-600 mb) 的文件,然后,由于我只能阻止读取字节集,我需要从每对字节构造短然后转换它浮点表示的缩写,因为我需要将样本存储为浮点数。

我当前的代码看起来像这样(比上面的方法性能提高了大约 2 倍,但仍然很长):

    float[] samples = new float[_samplesPerSplit];
    byte[] data = new byte[_samplesPerSplit * 2];

    for (int c = 0; c < numberOfChunks; c += 1)
    {
        br.Read(data, 0, _samplesPerSplit * 2);

        fixed (byte* bytePtr = data)
        {
            fixed (float* floatPtr = samples)
            {
                byte* rPos = bytePtr;
                float* fPos = floatPtr;

                byte byte0;
                byte byte1;
                short sampleShort;

                for (int sample = 0; sample < _samplesPerSplit; sample += 1)
                {
                    byte1 = *(rPos++);
                    byte0 = *(rPos++);

                    // I occasionaly get 
                    //          "Negating  the minimum value of a 
                    //          twos complement number is invalid" 
                    // error if i skip this check, but it slows down 
                    // whole process even more
                    if (byte0 == 128 && byte1 == 0)
                    {
                        sampleShort = 32767;
                    }
                    else
                    {
                        sampleShort = (short)(((ushort)(byte0)) << 8 | ((ushort)(byte1)));
                    }

                    *(fPos++) = (float)sampleShort;
                }
            }
        }
        ProcessChunk(samples);
    }

【问题讨论】:

    标签: c# file casting io type-conversion


    【解决方案1】:

    你可以试试这个:

        fixed (byte* bytePtr = data)
        {
            fixed (float* floatPtr = samples)
            {
                short* rPos = (short*)bytePtr;
                float* fPos = floatPtr;
    
                for (int sample = 0; sample < _samplesPerSplit; sample += 1)
                {
                    *fPos++ = (float)(*rPos++);
                }
    
            }
        }
    

    【讨论】:

    • 谢谢,似乎我的磁盘硬件有限,但我仍然可以节省大约 10% 左右的时间,所以我认为它现在很好,因为我无法想象有更快的速度:P
    【解决方案2】:

    您是否尝试过使用Bitwise operation

    我对它们了解不多,但我从 Wiki 和我的previous SO 那里了解到了关于它的信息:

    按位运算通常比乘法和除法运算快得多。

    【讨论】:

    • 他在第二个例子中已经使用了左移运算符。
    猜你喜欢
    • 1970-01-01
    • 2021-05-13
    • 2012-02-08
    • 2023-03-20
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多