繁体   English   中英

如何提高OpenXml Excel电子表格工具中从SharedStringTable检索值的性能?

[英]How can I improve the performance of retrieving values from SharedStringTable in OpenXml Excel spreadsheet tools?

我正在使用DocumentFormat.OpenXml读取Excel电子表格。 我的代码存在性能瓶颈,该代码用于从SharedStringTable对象中查找单元格值(这似乎是某种针对单元格值的查找表):

var returnValue = sharedStringTablePart.SharedStringTable.ChildElements.GetItem(parsedValue).InnerText;

我创建了一个字典以确保只检索一次值:

if (dictionary.ContainsKey(parsedValue))
{
    return dictionary[parsedValue];
}

var fetchedValue = sharedStringTablePart.SharedStringTable.ChildElements.GetItem(parsedValue).InnerText;
dictionary.Add(parsedValue, fetchedValue);
return fetchedValue;

这样可以将执行时间减少近50%。 但是,我的指标表明,代码行从SharedStringTable对象中获取值仍需要208秒来执行123,951次。 还有其他方法可以优化此操作吗?

我会一次性将整个共享字符串表读入您的字典中,而不是根据需要查找每个值。 这将使您能够按顺序浏览文件,并为哈希查找准备好存储值,这将比为所需的每个值扫描SST效率更高。

在过程开始时运行以下内容将使您可以使用dictionary[parsedValue]访问每个值。

private static void LoadDictionary()
{
    int i = 0;

    foreach (var ss in sharedStringTablePart.SharedStringTable.ChildElements)
    {
        dictionary.Add(i++, ss.InnerText);
    }
}

如果文件很大,则使用SAX方法而不是上面的DOM方法读取文件可能会带来一些好处:

private static void LoadDictionarySax()
{
    using (OpenXmlReader reader = OpenXmlReader.Create(sharedStringTablePart))
    {
        int i = 0;
        while (reader.Read())
        {
            if (reader.ElementType == typeof(SharedStringItem))
            {
                SharedStringItem ssi = (SharedStringItem)reader.LoadCurrentElement();
                dictionary.Add(i++, ssi.Text != null ? ssi.Text.Text : string.Empty);
            }
        }
    }
}

在我的机器上,使用具有60000行和2列的文件,使用上面的LoadDictionary方法而不是问题中的GetValue方法,速度快了大约300倍。 LoadDictionarySax方法提供了相似的性能,但是在较大的文件(100000行,10列)上,SAX方法比LoadDictionary方法快25%。 在更大的文件(100000行,26列)上, LoadDictionary方法抛出内存LoadDictionarySax异常,但LoadDictionarySax工作。

暂无
暂无

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

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