Unity Excel读写效率优化

在我的上一篇博文: unity Excel读写 实现了unity下的Excel读写,但是这种读写方式在大规模读写的情况下,比方说次数过万的情况下,时间会很糟糕,所以本文提出了一种优化方法做优化,不多说,先放优化结果

可以看到,30万次的写入总共花费时长5s,没有改进的话写入几百次花费的时间就会超过这个时间。

30万次读取总共花费7s。

大概的思路就是之前的读写每次都会New很多类出来,new类是很费性能的,我们把需要的类记录下来下次使用,就可以节省很多时间。代码如下:

改进后的Excel写入代码

    
    public static Dictionary<string, ExcelWorksheet> ExcelSheetDict;
    public static Dictionary<string, ExcelPackage> ExcelPackageDict;   

    /// <summary>
    /// 获取指定路径sheet的方式
    /// </summary>
    /// <param name="sheet"></param>
    public static void GetPackageAndSheet(string excelPath, string sheetName)
    {
        if (ExcelPackageDict == null)
        {
            ExcelPackageDict = new Dictionary<string, ExcelPackage>();
            ExcelSheetDict = new Dictionary<string, ExcelWorksheet>();
        }
        ExcelWorksheet worksheet;
        if (ExcelSheetDict.ContainsKey(excelPath + sheetName))
        {
            return;
        }
        else
        {
            FileInfo newFile = new FileInfo(excelPath);
            if (!newFile.Exists)
            {
                //不存在,创建
                CreatEmptyExcel(excelPath);
                newFile = new FileInfo(excelPath);
            }
            ExcelPackage package = new ExcelPackage(newFile);
            worksheet = package.Workbook.Worksheets[sheetName];
            if (worksheet == null)
            {
                //sheet不存在,创建
                worksheet = package.Workbook.Worksheets.Add(sheetName);
            }
            ExcelSheetDict.Add(excelPath + sheetName, worksheet);
            ExcelPackageDict.Add(excelPath + sheetName, package);
        }  
    }


    /// <summary>
    /// 写入excel
    /// </summary>
    /// <param name="text">要写入的文本</param>
    /// <param name="position">写入文本的位置,行序号和列序号</param>
    /// <param name="excelPath">Excel的路径,包含excel名称</param>
    /// <param name="sheetName">sheet名称,默认为sheet1</param>
    /// <param name="isCreat">excel不存在时是否创建,默认创建</param>
    /// <param name="isSave">写入完成时是否保存</param>
    public static void WriteExcel(string text,int[] position, string excelPath, bool isSave = true, string sheetName = "sheet1", bool isCreat = true)
    {
        GetPackageAndSheet(excelPath, sheetName);

        ExcelSheetDict[excelPath + sheetName].Cells[position[0], position[1]].Value = text;

        if (isSave) ExcelPackageDict[excelPath + sheetName].Save();
    }

测试代码:

    int Count = 300000; 
    public void WriteTest()
    {
        //Excel置空,加速时间
        ExportExcel.ClearExcel(ExportExcel.LangExcel);
        int[] value = new int[2] { 1, 1 };

        Log.Error("写入次数: " + Count + "次");
        System.DateTime time = System.DateTime.Now;
        Log.Error("写入开始时间: " + time.Hour + ":" + time.Minute + ":" + time.Second);
        for (int i = 1; i < Count ; i++)
        {
            value[0] = i;
            ExportExcel.WriteExcel(i.ToString(), value, ExportExcel.LangExcel, false);
        }

        time = System.DateTime.Now;
        Log.Error("写入结束时间: " + time.Hour + ":" + time.Minute + ":" + time.Second);
        ExportExcel.SavePackage(ExportExcel.LangExcel);
        time = System.DateTime.Now;
        Log.Error("保存结束时间: " + time.Hour + ":" + time.Minute + ":" + time.Second);
    }

需要提醒的是,如果写入的Excel不是空的话,花费的时长会非常夸张,所以我的做法是创建新的Excel写入,如果不是新的Excel保存数据花费时间会很长。

上面是对写入的改写

    public static Dictionary<string, DataSet> DataSetDict; 
    /// <summary>
    /// ExcelDataReader方式读取数据,在读取包含非字符串格式的Excel(如数字等)会报错,但是读取 速度很快
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public static string Read(string path, int[] position, bool isUpdaeDataSet = true)
    {
        if (DataSetDict == null)
        {
            DataSetDict = new Dictionary<string, DataSet>();
        }
        if (isUpdaeDataSet)
        {
            if (DataSetDict.ContainsKey(path)) DataSetDict.Remove(path);
        }
        if (!DataSetDict.ContainsKey(path))
        {
            FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
            IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
            DataSet result = excelReader.AsDataSet();
            DataSetDict.Add(path, result);
        }

        object value;
        string text;
        try
        {
            value = DataSetDict[path].Tables[0].Rows[position[0]][position[1]];
        }
        catch (System.Exception)
        {

            text = string.Empty;
            Log.Error("没那么多");

            return text;
            throw;
        }
        text = DataSetDict[path].Tables[0].Rows[position[0]][position[1]].ToString();
        return text;
    }

读取测试代码

    /// <summary>
    /// 读取测试,读取Count次
    /// </summary>
    public void ReadTestReader()
    {
        List<string> text = new List<string>();
        int[] value = new int[2] { 0, 0 };
        Log.Error("读取次数: " + Count + "次");
        System.DateTime time = System.DateTime.Now;
        Log.Error("读取开始时间: " + time.Hour + ":" + time.Minute + ":" + time.Second);
        ExportExcel.Read(ExportExcel.LangExcel, value);
        for (int i = 0; i < Count; i++)
        {
            value[0] = i;
            text.Add(Read(ExportExcel.LangExcel, value,false));
        }
        time = System.DateTime.Now;
        Log.Error("读取结束时间: " + time.Hour + ":" + time.Minute + ":" + time.Second);
    }

猜你喜欢

转载自blog.csdn.net/weixin_42275416/article/details/82491645