• 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
  • 相关阅读:
    线性表的链式存储的基本
    每天一个知识点- 线程池中线程执行任务发生异常会怎么样
    一篇文章带你全面了解智能地面水处理一体机
    spring boot整合redis—邮箱验证码
    有个开发者总结这 15 优雅的 JavaScript 个技巧
    mac苹果电脑系统最好用的清理软件CleanMyMac2024功能介绍及如何激活解锁许可证
    102. 二叉树的层序遍历
    Java中线程安全的集合
    TS_开发一个项目
    JavaWeb后端开发 JWT令牌解析 登录校验 通用模板/SpringBoot整合
  • 原文地址:https://blog.csdn.net/weixin_45029839/article/details/134009240