繁体   English   中英

随机化真正巨大的文本文件的行

[英]Randomize lines of really huge text file

我想将文件中的行随机化,该文件包含超过3200万行10位数字符串。 我知道如何使用File.ReadAllLines(...).OrderBy(s => random.Next()).ToArray()但这不是内存效率,因为它会将所有内容加载到内存中(超过1.4GB) )并且仅适用于x64架构。

另一种方法是拆分它并随机化较短的文件然后合并它们但我想知道是否有更好的方法来做到这一点。

您当前的方法将分配至少2个大型字符串数组(可能更多 - 我不知道OrderBy是如何实现的,但它可能会自己进行分配)。

如果通过在行之间进行随机排列(例如使用Fisher-Yates shuffle )来“就地”随机化数据,它将最小化内存使用。 当然,如果文件很大,它仍然会很大,但是你不会分配超过必要的内存。


编辑:如果所有行都具有相同的长度(*),则意味着您可以随机访问文件中的给定行,因此您可以直接在文件中执行Fisher-Yates shuffle。

(*)并假设您没有使用字符可以具有不同字节长度的编码,例如UTF-8

此应用程序使用字节数组演示您想要的内容

  1. 它创建一个填充数字为0到32000000的文件。
  2. 它加载文件,然后使用块复制Fisher-Yates方法将它们在内存中混洗。
  3. 最后,它以洗牌顺序将文件写回

峰值内存使用量约为400 MB。 在我的机器上运行大约20秒(主要是文件IO)。

public class Program
{
    private static Random random = new Random();

    public static void Main(string[] args)
    {
        // create massive file
        var random = new Random();
        const int lineCount = 32000000;

        var file = File.CreateText("BigFile.txt");

        for (var i = 0; i < lineCount ; i++)
        {
            file.WriteLine("{0}",i.ToString("D10"));
        }

        file.Close();

        int sizeOfRecord = 12;

        var loadedLines = File.ReadAllBytes("BigFile.txt");

        ShuffleByteArray(loadedLines, lineCount, sizeOfRecord);

        File.WriteAllBytes("BigFile2.txt", loadedLines);
    }

    private static void ShuffleByteArray(byte[] byteArray, int lineCount, int sizeOfRecord)
    {
        var temp = new byte[sizeOfRecord];

        for (int i = lineCount - 1; i > 0; i--)
        {
            int j = random.Next(0, i + 1);
            // copy i to temp
            Buffer.BlockCopy(byteArray, sizeOfRecord * i, temp, 0, sizeOfRecord);
            // copy j to i
            Buffer.BlockCopy(byteArray, sizeOfRecord * j, byteArray, sizeOfRecord * i, sizeOfRecord);
            // copy temp to j
            Buffer.BlockCopy(temp, 0, byteArray, sizeOfRecord * j, sizeOfRecord);
        }
    }
}

暂无
暂无

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

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