简体   繁体   English

如何提高XML文档的加载速度

[英]How can I improve the speed of loading xml documents

I need to load 2 types of xml documents; 我需要加载2种类型的xml文档; one has 50 sub-children and the other has the same 50 and 800 additional ones. 一个孩子有50个子孩子,另一个孩子又有50个和800个孩子。 Performance is great with the smaller doc and acceptable with the larger doc until the number of children increases. 对于较小的文档,性能很好;对于较大的文档,在子级数增加之前,性能是可以接受的。 20k children * 50 sub-children = great performance, 20k children * 850 sub-children = slow performance. 2万个孩子* 50个子孩子=出色的表现,2万个孩子* 850个子孩子=慢的表现。 How would I skip looking for the extra descendants when they do not exist? 如果不存在多余的后代,我将如何跳过它们? My initial attempts lead me to think I need have separate classes, methods, viewmodels, and views for both the small and large docs. 最初的尝试使我认为我需要为小型和大型文档使用单独的类,方法,视图模型和视图。 Below is a condensed look at my code. 下面是我的代码的简要介绍。

public class MyItem
    {
        private string layout;
        private string column;
        private string columnSpan;
        private string row;
        private string rowSpan;
        private string background;

public MyItem(string layout, string column, string columnSpan, string row, string rowSpan, string background)
{
        Layout = layout;
        Column = column;
        ColumnSpan = columnSpan;
        Row = row;
        RowSpan = rowSpan;
        Background = background;
}

public string Layout
    {
        get { return this.layout; }
        set { this.layout = value; }
    }

(Not Shown - Column, ColumnSpan, Row, RowSpan, and Background which are handled the same way as Layout) (未显示-列,列跨度,行,行跨度和背景的处理方式与布局相同)

Just for this example, below shows only 6 sub-children, I am looking for a way to load xml docs with only the first 2 sub-children. 仅就此示例而言,下面仅显示6个子孩子,我正在寻找一种仅使用前2个子孩子来加载xml文档的方法。 This way I can use whatever load method is required by both small or large xml docs. 这样,我可以使用小型或大型xml文档所需的任何加载方法。

internal class myDataSource
{
    //Loads (MyList) xml file 

    public static List<MyItem> Load(string MyListFilename)
    {

        var myfiles = XDocument.Load(MylistFilename).Descendants("item").Select(
            x => new MyItem(
                (string)x.Element("layout"),
                (string)x.Element("column"),
                (string)x.Element("columnSpan"),
                (string)x.Element("row"),
                (string)x.Element("rowSpan"),
                (string)x.Element("background")));

    return myfiles.ToList();
    }

public class MainViewModel : ViewModelBase
{

public void LoadMyList()
        {   

            this.myfiles = new ObservableCollection<MyItemViewModel>();

            List<MyItem> mybaseList = myDataSource.Load(MyListFilename);

            foreach (MyItem myitem in mybaseList)
            {
                this.myfiles.Add(new MyItemViewModel(myitem));
            }


            this.mycollectionView = (ICollectionView)CollectionViewSource.GetDefaultView(myfiles);
            if (this.mycollectionView == null)
                throw new NullReferenceException("mycollectionView");                
        }
}

 public class MyItemViewModel: ViewModelBase
{

    private Models.MyItem myitem;


    public MyItemViewModel(MyItem myitem)
    {
        if (myitem == null)
            throw new NullReferenceException("myitem");

        this.myitem = myitem;
    }      


    public string Layout
    {
        get
        {
            return this.myitem.Layout;
        }
        set
        {
            this.myitem.Layout = value;
            OnPropertyChanged("Layout");
        }
    }

(Not Shown - Column, ColumnSpan, Row, RowSpan, and Background which are handled the same way as Layout) (未显示-列,列跨度,行,行跨度和背景的处理方式与布局相同)

Instead of using Descendants , can you follow the direct path (ie use Elements )? 您可以使用直接路径(即使用Elements )来代替Descendants吗? That's the only way you'll keep from scanning nodes you know don't have items. 这是您避免扫描没有物品的节点的唯一方法。

i think one thing you can do is not do a toList on the Select and keep it as lazy, and return an Iterable instead, or whatever Select returns.(sorry, i don't have a windows box right now to test this on). 我认为您可以做的一件事不是在Select上执行toList并将其保持为惰性,然后返回Iterable,或其他Select返回。(对不起,我现在没有Windows框可以对此进行测试) 。 when you do the foreach, you will iterate over it only once (instead of twice right now) 当您执行foreach时,您只需对其进行一次迭代(而不是现在的两次)

XDocument is handy, but if the problem is simply that the files are large and you only have to scan once through, XmlReader might be the better choice. XDocument很方便,但是如果问题仅在于文件很大而您只需要扫描一次,XmlReader可能是更好的选择。 It doesn't read the entire file, it reads one node at a time. 它不会读取整个文件,而是一次读取一个节点。 You can manually skip through parts you are not interested in. 您可以手动跳过不感兴趣的部分。

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

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