• C# 写入文件比较


    数据长度:128188个long

    BinaryWriter每次写一个long 耗时14.7828ms
    StreamWriter每次写一个long 耗时44.0934 ms
    FileStream每次写一个long 耗时20.5142 ms

    FileStream固定chunk写入,循环操作数组,耗时13.4126 ms

    	byte[] chunk = new byte[datalist.Count * 8];
    	for (int i = 0; i < datalist.Count; i++) {
    	    long data = datalist[i];
    	    var bs = BitConverter.GetBytes(data);
    	    var startIndex = i * 8;
    	    for (int j = 0; j < 8; j++) {
    	        chunk[startIndex + j] = bs[j];
    	    }
    	}
    	fs.Write(chunk, 0, chunk.Length);
    	startTime.Stop();
    	lg.i($"{((float)startTime.ElapsedTicks / Stopwatch.Frequency) * 1000} ms");
    	fs.Flush();
    	fs.Close();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    FileStream固定chunk写入,直接操作数组,耗时10.2729 ms

    	byte[] chunk = new byte[datalist.Count * 8];
    	for (int i = 0; i < datalist.Count; i++) {
    	    long data = datalist[i];
    	    var bs = BitConverter.GetBytes(data);
    	    var startIndex = i * 8;
    	    chunk[startIndex] = bs[0];
    	    chunk[startIndex + 1] = bs[1];
    	    chunk[startIndex + 2] = bs[2];
    	    chunk[startIndex + 3] = bs[3];
    	    chunk[startIndex + 4] = bs[4];
    	    chunk[startIndex + 5] = bs[5];
    	    chunk[startIndex + 6] = bs[6];
    	    chunk[startIndex + 7] = bs[7];
    	}
    	fs.Write(chunk, 0, chunk.Length);
    	startTime.Stop();
    	lg.i($"{((float)startTime.ElapsedTicks / Stopwatch.Frequency) * 1000} ms");
    	fs.Flush();
    	fs.Close();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    经排查BitConverter.GetBytes源码如下,是上面比较耗时的地方,并且每次都会创建数组

    public static unsafe byte[] GetBytes(long value) 
    {
        byte[] bytes = new byte[8];
        fixed(byte* b = bytes)
            *((long*)b) = value;
        return bytes;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可以将上面改进一下,直接将代码内联进入上面代码上, 耗时2.8165 ms

    public static unsafe byte[] GetBytes(List<long> values) {
        byte[] bytes = new byte[values.Count * sizeof(long)];
        fixed (byte* ptr = bytes) {
            long* longPtr = (long*)ptr;
            for (int i = 0; i < values.Count; i++) {
                *longPtr = values[i];
                longPtr++;
            }
        }
        return bytes;
    }
    
    
    var startTime = new Stopwatch();
    startTime.Start();
    var fs = new FileStream(saveDataPath, FileMode.Append);
    byte[] chunk = GetBytes(datalist);
    fs.Write(chunk, 0, chunk.Length);
    startTime.Stop();
    lg.i($"{((float)startTime.ElapsedTicks / Stopwatch.Frequency) * 1000} ms");
    fs.Flush();
    fs.Close();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    由对称引起的空间结构耦合效应
    javascript设计模式 持续追加
    MATLAB中movmean函数用法
    Nas搭建webdav服务器并同步Zotero科研文献
    Laravel文档阅读笔记-Adding a Markdown editor to Laravel
    效率系列(九) macOS入门各式快捷操作
    华为OD机考题(HJ71 字符串通配符)
    Oracle的基本使用
    【spring源码系列】之【FactoryBean类型的接口】
    修改一个MD5的VB源码,使用它支持UTF8编码
  • 原文地址:https://blog.csdn.net/weixin_45029839/article/details/134009240