Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将90000 XElement添加到XDocument_C#_Linq_.net 3.5_C# 3.0_Linq To Xml - Fatal编程技术网

C# 将90000 XElement添加到XDocument

C# 将90000 XElement添加到XDocument,c#,linq,.net-3.5,c#-3.0,linq-to-xml,C#,Linq,.net 3.5,C# 3.0,Linq To Xml,我有一本字典 它包含100000个项目 10000项值填充,90000项为空 我有以下代码: var nullitems = MyInfoCollection.Where(x => x.Value == null).ToList(); nullitems.ForEach(x => LogMissedSequenceError(x.Key + 1)); private void LogMissedSequenceError(long SequenceNumber) {

我有一本
字典

它包含100000个项目

10000项值填充,90000项为空

我有以下代码:

var nullitems = MyInfoCollection.Where(x => x.Value == null).ToList();
nullitems.ForEach(x => LogMissedSequenceError(x.Key + 1));

private void LogMissedSequenceError(long SequenceNumber)
        {
            DateTime recordTime = DateTime.Now;

            var errors = MyXDocument.Descendants("ERRORS").FirstOrDefault();
            if (errors != null)
            {

                errors.Add(
                    new XElement("ERROR",
                        new XElement("DATETIME", DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss:fff")),
                        new XElement("DETAIL", "No information was read for expected sequence number " + SequenceNumber),
                        new XAttribute("TYPE", "MISSED"),
                        new XElement("PAGEID", SequenceNumber)
                        )
                );
            }
        }
这似乎需要大约2分钟才能完成。我似乎找不到瓶颈在哪里,或者这个时间听起来是否合适


有人知道为什么要花这么长时间吗?

这是我最有可能做的

private void BuildErrorNodes()
{
    const string nodeFormat = @"<ERROR TYPE=""MISSED""><DATETIME>{0}</DATETIME><DETAIL>No information was read for expected sequence number {1}</DETAIL><PAGEID>{1}</PAGEID></ERROR>";

    var sb = new StringBuilder("<ERRORS>");
    foreach (var item in MyInfoCollection)
    {
        if (item.Value == null) 
        {
            sb.AppendFormat(
                nodeFormat,
                DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss:fff"),
                item.Key + 1
            );
        }
    }

    sb.Append("</ERRORS>");

    var errorsNode = MyXDocument.Descendants("ERRORS").FirstOrDefault();
    errorsNode.ReplaceWith(XElement.Parse(sb.ToString()));
}
private void BuildErrorNodes()
{
常量字符串nodeFormat=@“{0}未读取预期序列号{1}{1}的信息”;
var sb=新的StringBuilder(“”);
foreach(MyInfoCollection中的变量项)
{
如果(item.Value==null)
{
附文格式(
nodeFormat,
DateTime.Now.ToString(“dd/MM/yyyy HH:MM:ss:fff”),
项。键+1
);
}
}
某人加上(“”);
var errorsNode=MyXDocument.subjections(“ERRORS”).FirstOrDefault();
errorsNode.ReplaceWith(XElement.Parse(sb.ToString());
}

如果您的
MyInfoCollection
很大,我不会对其调用
ToList()
,只是为了使用
ForEach
扩展方法。调用
ToList()
将创建并填充一个巨大的列表。我将删除
ToList()
调用,并将
.ForEach
转换为每个
语句的
,或者为
IEnumerable
编写一个.code>ForEach
扩展方法

然后对其进行轮廓分析,看看需要多长时间。另一件事是删除
ERRORS
元素的find和null检查。如果不存在,则不要为上面的每个
语句调用
。这样你就可以一次检查空值,而不是90000次

另外,正如Michael Stum指出的,我会定义一个字符串来保存值
DateTime.Now.ToString(“dd/MM/yyyy HH:MM:ss:fff”)
,然后引用或传递它。另外,你甚至不用这个电话:

DateTime recordTime = DateTime.Now;

用LINQ查询替换方法调用怎么样

static void Main(string[] args)
{

    var MyInfoCollection = (from key in Enumerable.Range(0, 100000)
                            let value = (MoreRandom() % 10 != 0)
                                                    ? (string)null
                                                    : "H"
                            select new { Value = value, Key = key }
                           ).ToDictionary(k => k.Key, v => v.Value);

    var MyXDocument = new XElement("ROOT",
                                    new XElement("ERRORS")
                                  );
    var sw = Stopwatch.StartNew();
    //===
    var errorTime = DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss:fff");
    var addedIndex = MyInfoCollection.Select((item, index) =>
                                                    new
                                                    {
                                                        Value = item.Value,
                                                        Key = item.Key,
                                                        Index = index
                                                    });
    var errorQuery = from item in addedIndex
                     where string.IsNullOrEmpty(item.Value)
                     let sequenceNumber = item.Key + 1
                     let detail = "No information was read for expected " +
                                  "sequence number " + sequenceNumber
                     select new XElement("ERROR",
                        new XElement("DATETIME", errorTime),
                        new XElement("DETAIL", detail),
                        new XAttribute("TYPE", "MISSED"),
                        new XElement("PAGEID", sequenceNumber)
                        );

    var errors = MyXDocument.Descendants("ERRORS").FirstOrDefault();
    if (errors != null)
        errors.Add(errorQuery);
    //===
    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds); //623
}
static RandomNumberGenerator rand = RandomNumberGenerator.Create();
static int MoreRandom()
{
    var buff = new byte[1];
    rand.GetBytes(buff);
    return buff[0];
}

使用调试跟踪查看查询需要多长时间,以及日志记录需要多长时间。此外,在处理100000个项目的文档时,XML可能会有大量的处理开销。您是否运行了探查器?我很感兴趣的是为什么要运行DateTime.now两次(因为调用它相对比较昂贵),以及当调用90k次时它的速度有多慢……我删除了DateTime,只调用一次并将其作为字符串传递。我还没有VisualStudioTeamETC中的分析器。如果你检查一下,你可能会发现在每次调用中查找“ERRORS”元素是最昂贵的部分之一。要么将ERRORS元素传递给该方法,要么使用LINQ,就像我在下面提到的那样。到目前为止,我刚刚实现了foreach循环,而不是foreach扩展方法,它们看起来速度相同。ToList()很快,只是日志记录占用了时间。@Jon:let允许您分配上下文变量。这就像在foreach循环中创建变量赋值一样。您可以将相同的信息放在“select”语句中,但我发现该模型更易于理解和重用。我还使用DateTime.Now在LINQ查询中进行了测试。它确实稍微减慢了这个过程,但不像反复查找“ERRORS”元素那样。谢谢!在PageID元素而不是序列号上,我需要集合中的位置。这可能吗?@Jon:let语句上的sequenceNumber的计算方法与您的示例相同。但是有一个重载。Select允许您获取项在IEnumerable集中的位置。我将在我的答案中添加一个例子。@Jon:我更新了我的例子,包括使用IEnumerable集合之外的position。