1

我有一个 ADO 数据集,我通过 ReadXml 从其 XML 文件加载。数据和模式位于不同的文件中。

现在,加载这个 DataSet 需要将近 13 秒。如果我不读取 DataSet 的架构并让 ReadXml 推断架构,我可以将其缩短到 700 毫秒,但是生成的 DataSet 不包含任何约束。

我试过这样做:

Console.WriteLine("Reading dataset with external schema.");
ds.ReadXmlSchema(xsdPath);
Console.WriteLine("Reading the schema took {0} milliseconds.", sw.ElapsedMilliseconds);
foreach (DataTable dt in ds.Tables)
{
   dt.BeginLoadData();
}
ds.ReadXml(xmlPath);
Console.WriteLine("ReadXml completed after {0} milliseconds.", sw.ElapsedMilliseconds);
foreach (DataTable dt in ds.Tables)
{
   dt.EndLoadData();
}
Console.WriteLine("Process complete at {0} milliseconds.", sw.ElapsedMilliseconds);

当我这样做时,读取架构需要 27 毫秒,读取数据集需要 12000 多毫秒。这是我在所有 DataTables 上调用 EndLoadData之前报告的时间。

这不是一个庞大的数据量——大约 1.5mb,没有嵌套关系,所有的表都包含两到三列 6-30 个字符。如果我预先阅读架构,我唯一能想到的不同之处在于架构包含所有唯一约束。但是 BeginLoadData 应该关闭约束(以及更改通知等)。所以这不应该在这里适用。(是的,我尝试将 EnforceConstraints 设置为 false。)

我已经阅读了许多关于人们通过首先读取架构而不是让对象推断架构来改善 DataSets 加载时间的报告。在我的例子中,推断架构的过程比明确提供架构快约 20 倍。

这让我有点疯狂。这个 DataSet 的模式是由元信息生成的,我很想编写一个方法来以编程方式创建它,并使用 XmlReader 对其进行反序列化。但我宁愿不这样做。

我错过了什么?我还能做些什么来提高这里的速度?

4

3 回答 3

1

我将尝试为您提供将数据存储在纯文本文件和 xml 文件中的性能比较。

第一个函数创建两个文件:一个包含 1000000 条纯文本记录的文件和一个包含 1000000 条(相同数据)记录的 xml 文件。首先,您必须注意文件大小的差异:~64MB(纯文本)与~102MB(xml文件)。

void create_files()
    {
        //create text file with data
        StreamWriter sr = new StreamWriter("plain_text.txt");

        for(int i=0;i<1000000;i++)
        {
            sr.WriteLine(i.ToString() + "<SEP>" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbb" + i.ToString());
        }

        sr.Flush();
        sr.Close();

        //create xml file with data
        DataSet ds = new DataSet("DS1");

        DataTable dt = new DataTable("T1");

        DataColumn c1 = new DataColumn("c1", typeof(int));
        DataColumn c2 = new DataColumn("c2", typeof(string));

        dt.Columns.Add(c1);
        dt.Columns.Add(c2);

        ds.Tables.Add(dt);

        DataRow dr;

        for(int j=0; j< 1000000; j++)
        {
            dr = dt.NewRow();
            dr[0]=j;
            dr[1] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbb" + j.ToString();
            dt.Rows.Add(dr);
        }

        ds.WriteXml("xml_text.xml");

    }

第二个函数读取这两个文件:首先它将纯文本读取到字典中(只是为了模拟使用它的真实世界),然后读取 XML 文件。这两个步骤都以毫秒为单位(并将结果写入控制台):

开始将文本文件读入内存
文本文件在 7628 毫秒内加载到内存中
开始将 XML 文件读
入内存 在 21018 毫秒内将 XML 文件加载到内存中

void read_files()
    {

        //timers
        Stopwatch stw = new Stopwatch();
        long milliseconds;

        //read text file in a dictionary

        Debug.WriteLine("Start read Text file into memory");

        stw.Start();
        milliseconds = 0;

        StreamReader sr = new StreamReader("plain_text.txt");
        Dictionary<int, string> dict = new Dictionary<int, string>(1000000);
        string line;
        string[] sep = new string[]{"<SEP>"};
        string [] arValues;
        while (sr.EndOfStream!=true) 
        {
            line = sr.ReadLine();
            arValues = line.Split(sep,StringSplitOptions.None);
            dict.Add(Convert.ToInt32(arValues[0]),arValues[1]);
        }

        stw.Stop();
        milliseconds = stw.ElapsedMilliseconds;

        Debug.WriteLine("Text file loaded into memory in " + milliseconds.ToString() + " milliseconds" );



        //create xml structure
        DataSet ds = new DataSet("DS1");

        DataTable dt = new DataTable("T1");

        DataColumn c1 = new DataColumn("c1", typeof(int));
        DataColumn c2 = new DataColumn("c2", typeof(string));

        dt.Columns.Add(c1);
        dt.Columns.Add(c2);

        ds.Tables.Add(dt);

        //read xml file

        Debug.WriteLine("Start read XML file into memory");

        stw.Restart();
        milliseconds = 0;

        ds.ReadXml("xml_text.xml");

        stw.Stop();
        milliseconds = stw.ElapsedMilliseconds;

        Debug.WriteLine("XML file loaded into memory in " + milliseconds.ToString() + " milliseconds");

    }

结论:XML 文件大小几乎是文本文件大小的两倍,加载速度比文本文件慢三倍。

XML 处理比纯文本更方便(因为抽象级别),但它更消耗 CPU/磁盘。

因此,如果您有小文件并且从性能的角度来看是可以接受的,那么 XML 数据集就更好了。但是,如果您需要性能,我不知道 XML 数据集(使用任何可用的方法)是否比纯文本文件更快。基本上,它从第一个原因开始:XML 文件更大,因为它有更多的标签。

于 2012-06-01T20:15:11.810 回答
0

确切地说,这不是一个答案(尽管总比没有好,这是我到目前为止所得到的),但是在解决这个问题很长时间之后,我发现当我的程序不在 Visual Studio 中运行时,它完全不存在。

我之前没有提到的,这使得这更加神秘的是,当我将一个不同的(但相当大的)XML 文档加载到 DataSet 中时,程序运行得很好。我现在想知道我的一个数据集是否附加了某种元信息,Visual Studio 在运行时检查而另一个没有。我不知道。

于 2008-12-03T02:39:09.170 回答
0

另一个要尝试的维度是在没有模式的情况下读取数据集,然后将其合并到启用了约束的类型化数据集中。这样,它在构建用于强制约束的索引时就拥有所有数据——也许它会更有效?

来自MSDN

Merge 方法通常在涉及验证更改、协调错误、使用更改更新数据源以及最后刷新现有 DataSet 的一系列过程结束时调用

.

于 2009-02-25T04:06:05.960 回答