简体   繁体   English

保存3D int数组的最快方法? (XNA \\ C#)

[英]Fastest Way to Save 3D int Array? (XNA \ C#)

I need a fast way to save a small 3D array to a file as quickly as possible. 我需要一种快速的方法来尽快将小型3D阵列保存到文件中。 The array is 32x32x4 in size. 该阵列的大小为32x32x4。 I also need a fast way of reading the file. 我还需要一种快速读取文件的方法。

So far I have tried looping through all the elements: 到目前为止,我已经尝试循环遍历所有元素:

for (int xx = 0; xx < 32; xx += 1)
{
    for (int yy = 0; yy < 32; yy += 1)
    {
        for (int zz = 0; zz < 4; zz += 1)
        {
            String += FormatInt(array[xx, yy, zz]);
        }
    }
}

Turning each integer into a string with 2 digits: (The FormatInt() method above) 将每个整数转换为2位数的字符串:(上面的FormatInt()方法)

public string FormatInt(int num)
    {
        string String = "";
        String = Convert.ToString(num);
        int length = String.Length;
        for (int i = 0; i < (2 - length); i += 1)
        {
            String = String.Insert(0, "0");
        }
        return String;
    }

Then saving that string to a .txt file. 然后将该字符串保存为.txt文件。 I then load the file, then turn each 2-digit substring into an integer: 然后我加载文件,然后将每个2位数的子字符串转换为整数:

int Pos = 0;
            for (int xx = 0; xx < chunkSize; xx += 1)
            {
                for (int yy = 0; yy < chunkSize; yy += 1)
                {
                    for (int zz = 0; zz < 4; zz += 1)
                    {
                        array[xx, yy, zz] = Convert.ToInt32(String.Substring(Pos * 2, 2));
                        Pos += 1;
                    }
                }
            }

I need a faster way of saving the file. 我需要一种更快的方法来保存文件。 (A faster loading would be nice too, but it's not too slow right now.) (更快的加载也会很好,但现在它不会太慢。)

I would use a BinaryReader and BinaryWriter . 我会使用BinaryReaderBinaryWriter Your current method is very inefficient at storage and is going to have memory problems appending so many strings with += (Use StringBuilder instead) 您当前的方法在存储时效率非常低,并且会出现内存问题,并使用+=附加如此多的字符串(使用StringBuilder

Saving: 保存:

using (BinaryWriter b = new BinaryWriter(File.Open("file.ext", FileMode.Create)))
{
    for (int xx = 0; xx < 32; xx += 1)
    {
        for (int yy = 0; yy < 32; yy += 1)
        {
            for (int zz = 0; zz < 4; zz += 1)
            {
                b.Write(array[xx, yy, zz]);
            }
        }
    }
}

Loading 载入中

using (BinaryReader b = new BinaryReader(File.Open("file.ext", FileMode.Open)))
{
    for (int xx = 0; xx < 32; xx += 1)
    {
        for (int yy = 0; yy < 32; yy += 1)
        {
            for (int zz = 0; zz < 4; zz += 1)
            {
                array[xx, yy, zz] = b.ReadInt32();
            }
        }
    }
}

This is far more effecient than writing a string to a file, you can event write Int16 s and Bytes if you have smaller data types. 这比将字符串写入文件更有效,如果您的数据类型较小,则可以使用事件写入Int16Bytes You can combine this with Gzip for very small files. 对于非常小的文件,您可以将其与Gzip结合使用。

Cyral's answer is sound. Cyral的回答是合理的。 But since you asked for the fastest possible way, my own tests indicate that using P/Invoke is about three times faster: 但是既然你要求尽可能快的方式,我自己的测试表明使用P / Invoke的速度提高了大约三倍:

[DllImport("kernel32.dll")]
private static extern bool WriteFile(IntPtr hFile, IntPtr lpBuffer, int nNumberOfBytesToWrite, out int lpNumberOfBytesWritten, IntPtr lpOverlapped);

private static unsafe void Write(Int32[,,] array)
{
    fixed (int* pArray = array)
    {
        using (var file = File.Open("filename", FileMode.Create, FileAccess.Write))
        {
            int written;
            WriteFile(file.SafeFileHandle.DangerousGetHandle(), (IntPtr)pArray, array.Length, out writter, IntPtr.Zero);
        }
    }
}

There's a corresponding ReadFile() function in kernel32.dll that can be used for reading, mutatis mutandis . kernel32.dll中有一个相应的ReadFile()函数,可以用于阅读, 比照变通

如果要使用字符串,请使用StringBuilder而不是String + =,因为它更有效

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM