.net部分运行缓慢

问题描述:

更新:Andrew和Conrad的答案同样有帮助。时间问题的简单修复解决了问题,并缓存了更大的对象引用,而不是每次移除问题源时重新构建它们。感谢您的意见,伙计们。.net部分运行缓慢

我正在使用c#.NET API,出于某种原因,下面的代码会执行我感觉非常/非常慢的操作。

这是一个System.Timers.Timer的处理程序,它每5秒触发一次它发生的事件。

private static void TimerGo(object source, System.Timers.ElapsedEventArgs e) 
    { 
     tagList = reader.GetData(); // This is a collection of 10 objects. 

     storeData(tagList); // This calls the 'storeData' method below 

    } 

而且storeData方法:

private static void storeData(List<obj> tagList) 
    { 
     TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1)); 
     long timestamp = (long)t.TotalSeconds; 

     foreach (type object in tagList) 
     { 
      string file = @"path\to\file" + object.name + ".rrd"; 

      RRD dbase = RRD.load(file); 

      // Update rrd with current time timestamp and data. 
      dbase.update(timestamp, new object[1] { tag.data }); 
     } 
    } 

我失去了一些明显的资源池?您看到的RRD内容来自rrdtool的NHawk C#封装器;在这种情况下,我用它更新了10个不同的文件,但我没有看到为什么它需要这么长时间。当我说“这么久”,我的意思是计时器在第一次更新完成之前第二次触发,所以最终“更新2”会在“更新1”之前发生,因为“更新1”具有早于“更新2”的时间戳。

我将计时器长度增加到10秒,并且运行时间更长,但仍然最终超出本身并尝试使用较早的时间戳更新文件。我可以采取什么不同的做法来提高效率,因为很明显,我正在做一些大大的错误...

+2

您是否尝试过分析rrd命令? – Alxandr 2011-05-31 21:08:26

+0

甚至可以剖析读者......从这段代码中无法分辨出实际问题。分析整个事情以确定时间花在哪里。此外,您还想知道文件系统在其他方面的负载情况。 – NotMe 2011-05-31 21:20:52

您的tagList中的每个标签是否存在不同的RRD文件?在你的伪代码中,你打开每个文件N次。 (你指出列表中只有10个对象被认为是)。然后你执行更新。我只能假设你在更新完RRD文件后才处理它。如果你不保存对一个打开文件的引用。

如果RRD是相同的,但您只是将不同类型的绘图数据放入单个文件中,那么只要您希望对其进行专有写入访问,就只需保持其打开状态即可。

没有谱,你有几个选项的代码(我推荐分析BTW)

保持RRD文件打开

缓存打开的文件,以防止您不必打开,写密切每5每个文件的秒数。只需缓存10个打开的文件引用并每5秒写入一次。

独立从数据写入

看样子你是从一些对象采取的度量样本每5秒的数据收集。如果你没有对文件进行“拖尾”处理,请将文章分开。把你的数据样本放入一个队列中进行处理。处理器将使每个tagList出列并尽可能快地写入,从队列中返回更多列表。

通过这种方式,即使写入机制变慢​​,您也可以确保获得约5秒的样本。

+0

是的,tagList中的每个元素都有一个单独的文件,编辑上述内容以反映这一点。使用NHawk库可以防止我对实际的文件处理有任何控制 - 据我所知,它只是一个方便的接口,用于执行一个进程。rrd可执行文件的开始(),然后处理所有的文件IO。 – uscere90 2011-05-31 21:34:23

+0

@ uscere90那么最好的办法是将数据收集与数据写入分开。如果您需要详细说明,我会更新我的答案。 – 2011-05-31 21:40:39

+0

如果你不介意详细说明,那会很棒。我现在正在与一名探查者一起玩,看看我是否可以缩小它瓶颈处的位置,但是设置一个排队系统以促进一致的写作似乎是一个很好的第二选择。 – uscere90 2011-05-31 22:01:49

使用探查器。 JetBrains是我个人的建议。使用程序运行分析器,并查找花费最长时间运行的线程/方法。这听起来非常像IO或数据问题,但从示例代码中看不出来。

并不真正回答你的perf问题,但是如果你想修复rentrancy位,你的timer.AutoRest设置为false,然后在方法结尾调用start()。

private static void TimerGo(object source, System.Timers.ElapsedEventArgs e) 
{ 
    tagList = reader.GetData(); // This is a collection of 10 objects. 

    storeData(tagList); // This calls the 'storeData' method below 
    timer.Start(); 
}