有没有更快的方法来存储/读取XML文档中的数据?

有没有更快的方法来存储/读取XML文档中的数据?,xml,vb.net,xml-parsing,xml-deserialization,Xml,Vb.net,Xml Parsing,Xml Deserialization,我一直在用VB.NET开发一个Windows窗体应用程序来解析一个大型XML文档,这是一本日英词典。我最初构建了一个基于字符串的解析器,它读取所有XML标记并手动提取它们的内容。完全解析XML文件平均需要30秒。在这一点上,我从来没有听说过反序列化 然后多亏了,我得到了一个正确的XML反序列化程序,它将XML文件中的所有数据加载到一个类对象中。明亮的但加载平均需要20秒 虽然效率提高了33%,但我想知道是否有更好的方法我没有意识到或没有考虑过。或者可能是我现有的代码/类定义中的低效,我至少可以减

我一直在用VB.NET开发一个Windows窗体应用程序来解析一个大型XML文档,这是一本日英词典。我最初构建了一个基于字符串的解析器,它读取所有XML标记并手动提取它们的内容。完全解析XML文件平均需要30秒。在这一点上,我从来没有听说过反序列化

然后多亏了,我得到了一个正确的XML反序列化程序,它将XML文件中的所有数据加载到一个类对象中。明亮的但加载平均需要20秒

虽然效率提高了33%,但我想知道是否有更好的方法我没有意识到或没有考虑过。或者可能是我现有的代码/类定义中的低效,我至少可以减少它

该文件有470万行长,显示了180000多个字典条目的信息,因此我准备接受可能没有更快的方法解析XML。我想知道是否有比XML文本文件格式更好的存储数据的替代方法,Windows窗体应用程序可以更快地读取XML文本文件格式

以下是我当前用于反序列化的代码:

Sub Deserialise()
    Dim settings As XmlReaderSettings = New XmlReaderSettings
    settings.DtdProcessing = DtdProcessing.Parse

    Dim xmlPath As String = Path.Combine(Application.StartupPath, jmdictpath)

    Dim serialiser As New XmlSerializer(GetType(JMdict))

    Using rdr As Xml.XmlReader = Xml.XmlReader.Create(xmlPath, settings)
        dict = CType(serialiser.Deserialize(rdr), JMdict)
    End Using
End Sub
下面是类定义:

<XmlRoot>
Public Class JMdict
    <XmlElement("entry")>
    Public Property entrylist As List(Of Entry)
End Class

<Serializable()>
<XmlType("entry")>
Public Class Entry
    <XmlElement("ent_seq")>
    Public Property EntrySequence As Integer
    <XmlElement("k_ele")>
    Public Property Keywords As List(Of KeywordElement)
    <XmlElement("r_ele")>
    Public Property Readings As List(Of ReadingElement)
    <XmlElement("sense")>
    Public Property Senses As List(Of SenseElement)
End Class

<Serializable()>
<XmlType("k_ele")>
Public Class KeywordElement
    <XmlElement("keb")>
    Public Property Keyword As String
    <XmlElement("ke_pri")>
    Public Property KeywordPriority As List(Of String)
    <XmlElement("ke_inf")>
    Public Property KeywordOrthography As List(Of String)
End Class

<Serializable()>
<XmlType("r_ele")>
Public Class ReadingElement

    <XmlElement("reb")>
    Public Property Reading As String
    <XmlElement("re_pri")>
    Public Property ReadingPriority As List(Of String)
    <XmlElement("re_inf")>
    Public Property ReadingOrthography As List(Of String)
    <XmlElement("re_restr")>
    Public Property ReadingToKeywordRestriction As List(Of String)

    Private _NotTrueReading As Boolean

    <XmlElement("re_nokanji")>
    Public Property NotTrueReading As String
        Get
            Return _NotTrueReading
        End Get
        Set
            If NotTrueReading IsNot Nothing Then
                _NotTrueReading = True
            Else
                _NotTrueReading = False
            End If
        End Set
    End Property
End Class

<Serializable()>
<XmlType("sense")>
Public Class SenseElement
    <XmlElement("pos")>
    Public Property PartOfSpeech As List(Of String)
    <XmlElement("gloss")>
    Public Property Gloss As List(Of GlossElement)

    <XmlElement("stagk")>
    Public Property SenseRestrictedToKeyword As List(Of String)
    <XmlElement("stagr")>
    Public Property SenseRestrictedToReading As List(Of String)

    <XmlElement("xref")>
    Public Property CrossReference As List(Of String)
    <XmlElement("ant")>
    Public Property Antonym As List(Of String)
    <XmlElement("field")>
    Public Property Field As List(Of String)
    <XmlElement("dial")>
    Public Property Dialect As List(Of String)
    <XmlElement("s_inf")>
    Public Property SenseInformation As List(Of String)
    <XmlElement("misc")>
    Public Property Misc As List(Of String)
    <XmlElement("lsource")>
    Public Property LanguageSource As List(Of LanguageSourceElement)
End Class


<Serializable()>
<XmlType("gloss")>
Public Class GlossElement
    <XmlAttribute("xml:lang")>
    Public Property Language As String
    <XmlAttribute("g_type")>
    Public Property GlossType As String
    <XmlText>
    Public Property Text As String
    Public Overrides Function ToString() As String
        Return Text
    End Function
End Class

<Serializable()>
<XmlType("lsource")>
Public Class LanguageSourceElement
    <XmlAttribute("xml:lang")>
    Public Property Language As String
    <XmlAttribute("ls_type")>
    Public Property LanguageSourceType As String

    Private _IsWaseieigo As Boolean
    <XmlAttribute("ls_wasei")>
    Public Property IsWaseieigo As String
        Get
            Return _IsWaseieigo
        End Get
        Set
            If IsWaseieigo = "y" Then
                _IsWaseieigo = True
            Else
                _IsWaseieigo = False
            End If
            '_IsWaseieigo = Value
        End Set
    End Property

    <XmlText>
    Public Property Text As String
    Public Overrides Function ToString() As String
        Return Text
    End Function

End Class

公共类JMdict
公共财产条目列表作为列表(条目)
末级
公开课入学
公共属性EntrySequence为整数
公共属性关键字作为(关键字元素的)列表
公共财产读数作为列表(ReadingElement的)
公共财产感官列表(感官元素)
末级
公共类关键字元素
公共属性关键字作为字符串
公共属性关键字优先级作为列表(字符串)
公共属性关键字正交作为列表(字符串)
末级
公共类ReadingElement
作为字符串读取的公共属性
公共属性读取优先级为列表(字符串)
公共属性读取或记录为列表(字符串)
公共属性ReadingToKeywordRestriction作为列表(字符串)
Private _NotTrueReading为布尔值
公共属性NotTrueReading为字符串
得到
返回非真实读数
结束
设置
如果不是真的,那么阅读也不是什么
_NotTrueReading=True
其他的
_NotTrueReading=错误
如果结束
端集
端属性
末级
公共类敏感元素
公共属性部分语音列表(字符串)
公共财产光泽作为列表(光泽元素)
公共财产SENSEREDTOKEYWORD As列表(字符串)
公共属性SenseRestrictedToReading As列表(字符串)
公共属性交叉引用作为列表(字符串)
公共属性反义词As列表(字符串)
作为列表的公共属性字段(字符串)
公共属性方言作为列表(字符串)
公共属性感知信息列表(字符串)
公共属性杂项作为列表(字符串)
公共属性LanguageSource作为列表(LanguageSourceElement的列表)
末级
公共类GlossElement
作为字符串的公共属性语言
公共属性GlossType为字符串
公共属性文本作为字符串
Public将函数ToString()重写为字符串
返回文本
端函数
末级
公共类LanguageSourceElement
作为字符串的公共属性语言
公共属性语言SourceType为字符串
Private_iswaseigo作为布尔值
公共属性iswaseigo作为字符串
得到
返回(Iswaseigo)
结束
设置
如果iswaseigo=“y”,则
_Iswaseigo=True
其他的
_Iswaseigo=False
如果结束
“"Iswaseigo=值
端集
端属性
公共属性文本作为字符串
Public将函数ToString()重写为字符串
返回文本
端函数
末级
我们怎么想?有没有希望更快地解决问题

编辑-以下是XML示例:

<entry>
<ent_seq>1486440</ent_seq>
<k_ele>
<keb>美術</keb>
<ke_pri>ichi1</ke_pri>
<ke_pri>news1</ke_pri>
<ke_pri>nf02</ke_pri>
</k_ele>
<r_ele>
<reb>びじゅつ</reb>
<re_pri>ichi1</re_pri>
<re_pri>news1</re_pri>
<re_pri>nf02</re_pri>
</r_ele>
<sense>
<pos>&n;</pos>
<pos>&adj-no;</pos>
<gloss>art</gloss>
<gloss>fine arts</gloss>
</sense>
<sense>
<gloss xml:lang="dut">kunst</gloss>
<gloss xml:lang="dut">schone kunsten</gloss>
</sense>
<sense>
<gloss xml:lang="fre">art</gloss>
<gloss xml:lang="fre">beaux-arts</gloss>
</sense>
<sense>
<gloss xml:lang="ger">Kunst</gloss>
<gloss xml:lang="ger">die schönen Künste</gloss>
<gloss xml:lang="ger">bildende Kunst</gloss>
</sense>
<sense>
<gloss xml:lang="ger">Produktionsdesign</gloss>
<gloss xml:lang="ger">Szenographie</gloss>
</sense>
<sense>
<gloss xml:lang="hun">művészet</gloss>
<gloss xml:lang="hun">művészeti</gloss>
<gloss xml:lang="hun">művészi</gloss>
<gloss xml:lang="hun">rajzóra</gloss>
<gloss xml:lang="hun">szépművészet</gloss>
</sense>
<sense>
<gloss xml:lang="rus">изящные искусства; искусство</gloss>
<gloss xml:lang="rus">{~{的}} художественный, артистический</gloss>
</sense>
<sense>
<gloss xml:lang="slv">umetnost</gloss>
<gloss xml:lang="slv">likovna umetnost</gloss>
</sense>
<sense>
<gloss xml:lang="spa">bellas artes</gloss>
</sense>
</entry>

1486440
美術
一1
新闻1
nf02
びじゅつ
一1
新闻1
nf02
&n;
&形容词否;
艺术
美术
昆斯特
肖恩·昆斯滕
艺术
美女艺术
艺术
迪舍内·昆斯特
比尔登德昆斯特
产品设计
Szenographie
művészet
művészeti
művészi
拉杰索拉
施佩姆·维塞特
изящные искусства; искусство
{~{的}} художественный, артистический
梅特诺斯特
利科夫纳乌梅特诺斯特酒店
贝拉斯阿尔特斯酒店

整个过程都包装在标记中

Try xml linq。下面的代码没有经过测试,因为您没有发布任何xml:

Imports System.Xml
Imports System.Xml.Linq
Imports System.IO
Module Module1
    Const FILENAME As String = "c:\temp\test.xml"
    Sub Main()
        Dim JMdict As JMdict = JMdict.Parse(FILENAME)
    End Sub

    Public Class JMdict
        Public Property entrylist As List(Of Entry)

        Public Shared Function Parse(filename As String) As JMdict
            Dim reader As New StreamReader(filename)
            reader.ReadLine()
            Dim doc As XDocument = XDocument.Load(reader)
            Dim newJMdict As New JMdict()
            Dim jmDict = doc.Root

            newJMdict.entrylist = jmDict.Elements("entry").Select(Function(x) Entry.Parse(x)).ToList()
            Return newJMdict
        End Function
    End Class

    Public Class Entry
        Public Property EntrySequence As Integer
        Public Property Keywords As List(Of KeywordElement)
        Public Property Readings As List(Of ReadingElement)
        Public Property Senses As List(Of SenseElement)

        Public Shared Function Parse(xEntry As XElement) As Entry
            Dim newEntry As New Entry()
            newEntry.EntrySequence = CType(xEntry.Element("ent_seq"), Integer)
            newEntry.Keywords = xEntry.Elements("k_ele").Select(Function(x) KeywordElement.Parse(x)).ToList()

            newEntry.Readings = xEntry.Elements("r_ele").Select(Function(x) ReadingElement.Parse(x)).ToList()
            newEntry.Senses = xEntry.Elements("sense").Select(Function(x) SenseElement.Parse(x)).ToList()


            Return newEntry
        End Function
    End Class

    Public Class KeywordElement
        Public Property Keyword As String
        Public Property KeywordPriority As List(Of String)
        Public Property KeywordOrthography As List(Of String)

        Public Shared Function Parse(xKeywordElement As XElement) As KeywordElement
            Dim newKeywordElement As New KeywordElement()
            newKeywordElement.Keyword = CType(xKeywordElement.Element("key"), String)
            newKeywordElement.KeywordPriority = xKeywordElement.Elements("ke_pri").Select(Function(x) CType(x, String)).ToList()
            newKeywordElement.KeywordOrthography = xKeywordElement.Elements("ke_inf").Select(Function(x) CType(x, String)).ToList()

            Return newKeywordElement
        End Function


    End Class

    Public Class ReadingElement

        Public Property Reading As String
        Public Property ReadingPriority As List(Of String)
        Public Property ReadingOrthography As List(Of String)
        Public Property ReadingToKeywordRestriction As List(Of String)

        Private _NotTrueReading As Boolean

        Public Property NotTrueReading As String
            Get
                Return _NotTrueReading
            End Get
            Set(value As String)
                If NotTrueReading IsNot Nothing Then
                    _NotTrueReading = True
                Else
                    _NotTrueReading = False
                End If
            End Set
        End Property

        Public Shared Function Parse(xReadingElement As XElement) As ReadingElement
            Dim newReadingElement As New ReadingElement
            newReadingElement.Reading = CType(xReadingElement.Element("reb"), String)
            newReadingElement.ReadingPriority = xReadingElement.Elements("re_pri").Select(Function(x) CType(x, String)).ToList()
            newReadingElement.ReadingOrthography = xReadingElement.Elements("re_inf").Select(Function(x) CType(x, String)).ToList()
            newReadingElement.ReadingToKeywordRestriction = xReadingElement.Elements("re_restr").Select(Function(x) CType(x, String)).ToList()

            newReadingElement.NotTrueReading = CType(xReadingElement.Element("re_nokanji"), String)

            Return newReadingElement
        End Function
    End Class

    Public Class SenseElement
        Public Property PartOfSpeech As List(Of String)
        Public Property Gloss As List(Of GlossElement)

        Public Property SenseRestrictedToKeyword As List(Of String)
        Public Property SenseRestrictedToReading As List(Of String)
        Public Property CrossReference As List(Of String)
        Public Property Antonym As List(Of String)
        Public Property Field As List(Of String)
        Public Property Dialect As List(Of String)
        Public Property SenseInformation As List(Of String)
        Public Property Misc As List(Of String)
        Public Property LanguageSource As List(Of LanguageSourceElement)

        Public Shared Function Parse(xSenseElement As XElement) As SenseElement
            Dim newSenseElement As New SenseElement
            newSenseElement.PartOfSpeech = xSenseElement.Elements("pos").Select(Function(x) CType(x, String)).ToList()
            newSenseElement.Gloss = xSenseElement.Elements("gloss").Select(Function(x) GlossElement.Parse(x)).ToList()
            newSenseElement.SenseRestrictedToKeyword = xSenseElement.Elements("stagk").Select(Function(x) CType(x, String)).ToList()
            newSenseElement.SenseRestrictedToReading = xSenseElement.Elements("stagr").Select(Function(x) CType(x, String)).ToList()
            newSenseElement.CrossReference = xSenseElement.Elements("xref").Select(Function(x) CType(x, String)).ToList()
            newSenseElement.Antonym = xSenseElement.Elements("ant").Select(Function(x) CType(x, String)).ToList()
            newSenseElement.Field = xSenseElement.Elements("field").Select(Function(x) CType(x, String)).ToList()
            newSenseElement.Dialect = xSenseElement.Elements("dial").Select(Function(x) CType(x, String)).ToList()
            newSenseElement.SenseInformation = xSenseElement.Elements("s_inf").Select(Function(x) CType(x, String)).ToList()
            newSenseElement.Misc = xSenseElement.Elements("misc").Select(Function(x) CType(x, String)).ToList()

            newSenseElement.LanguageSource = xSenseElement.Elements("lsource").Select(Function(x) LanguageSourceElement.Parse(x)).ToList()
            Return newSenseElement
        End Function
    End Class

    Public Class GlossElement
        Public Property Language As String
        Public Property GlossType As String
        Public Property Text As String

        Public Shared Function Parse(xGlossElement As XElement) As GlossElement
            Dim newGlossElement As New GlossElement

            newGlossElement.Language = CType(xGlossElement.Attributes().Where(Function(x) x.Name.LocalName = "lang").FirstOrDefault(), String)
            newGlossElement.GlossType = CType(xGlossElement.Attribute("g_type"), String)
            newGlossElement.Text = CType(xGlossElement, String)
            Return newGlossElement
        End Function
    End Class

    Public Class LanguageSourceElement

        Public Property Language As String
        Public Property LanguageSourceType As String

        Public IsWaseieigo As Boolean

        Public Property Text As String

        Public Shared Function Parse(xLanguageSourceElement As XElement) As LanguageSourceElement
            Dim newLanguageSourceElement As New LanguageSourceElement
            newLanguageSourceElement.Language = CType(xLanguageSourceElement.Attributes().Where(Function(x) x.Name.LocalName = "lang").FirstOrDefault(), String)
            newLanguageSourceElement.LanguageSourceType = CType(xLanguageSourceElement.Attribute("ls_type"), String)
            newLanguageSourceElement.IsWaseieigo = IIf(CType(xLanguageSourceElement.Attribute("ls_wasei"), String) = "y", True, False)
            newLanguageSourceElement.Text = CType(xLanguageSourceElement, String)
            Return newLanguageSourceElement
        End Function

    End Class
End Module

xml文件多久更改一次?即,您的最终用户是否真的需要每次都读取此文件?我的意思是,使用最初由xml数据填充的数据库会更好地服务于您的应用程序吗?xml文件根本不会更改,连接到数据库可能会更好地服务于应用程序我甚至编写了代码将所有数据传输到数据库,但出于某种原因,我认为读取数据的速度不如动态解析数据的速度快……我要试一试……不要使用序列化。它非常慢。Linq比序列化快得多。几周前,一个OP尝试了这个实验,其中序列化需要30秒几分钟后,xml linq立即返回结果。我怀疑是内存问题造成了很大的不同。当内存不足时,通过使用磁盘空间进行交换可以获得额外的内存。磁盘比内存慢得多。你能发布xml文件让我们尝试几件事吗?谢谢jdweng!我已经用一个xml示例更新了这个问题我刚解决了3个问题1)我在一个地方使用了解析而不是加载2)必须为uni添加修复