2012-03-27 101 views
0

我正在处理项目的一部分,它解析Postgres数据库服务器中的日志。 该应用程序是在C sharp Framework 4.0中开发的。从Datagridview行生成统计信息

日志产生和上一个DataGridView显示有以下的列

resultCode  Statement     Starttime     Duration 
XT001   select * from PizzaMade 01-02-2012 03:10:14   00:04:10 
  • 有许多loglines与sameformat。
  • 通过解析文本文件从另一个循环填充Datagridview。

我的工作是生成数据可用的统计信息网格的格式如下

Statement         Count  countpercent     Occurs_on 

select * from PizzaMade      3    1.42  01/02 at 03pm [00:04:10], 01/02 at 04 [00:01:04] 
select id,qty,table from PizzaMade   12    5.12   ........... 

所以基本的统计数据反映了以下

  • 一)语句执行
  • b )计数出现在网格中的次数
  • c)计数的百分比,其基本上是totalcounts此语句占据
  • d)含有开始时间级联串,持续时间

»该统计信息是作为数据表最初产生,使用for循环

foreach(DataGridViewRow dr in LogGrid.Rows) 
{ 
// search in the Datatable if the statement is present 
// if it is then add count , add starttime and duration to the column 
// if not then add a newrow 

} 

»填充DataTable之后,我用一个循环来计算Totalcount

int totalcount = 0; 
foreach (DataRow drin StatTable.Rows) 
{ 
totalcount = totalcount + Convert.ToInt32(dr["count"].ToString()); 
} 

»计算计后,有一个循环计算百分比

foreach (DataRow dr in StatTable.Rows) 
{ 
    int c = Convert.ToInt32(dr["count"].ToString()); 
    dr["countpercent"] = (c/totalcount)*100; 
} 

虽然一切看起来正常,整个方法是缓慢的具有大量的行。

  • 请问您能否提出改进性能的方法。

感谢 阿文德

+1

你可以尝试为获得总数使用DataTable的计算方法,但我不知道是否会提高性能 – mslliviu 2012-03-27 05:58:38

+0

我测试的计算方法上的100万所记录的样本数据,似乎foreach循环需要545ms并计算方法1850毫秒。即foreach循环更快 – arvind 2012-03-27 06:26:10

回答

1

既然你解析文本日志,它可能通过不格但在对象操作的增强性能。此外,网格可以绑定到解析日志列表。它可能是这样的:

public class LogItem 
{ 
    public string ResultCode { get;set;} 
    public string Statement { get;set;} 
    public DateTime StartTime { get;set;} 
    public TimeSpan Duration { get;set;} 
} 

然后你的网格可以绑定到包含所有解析日志项目的BindingList。虽然有列表,你可以在更统一的方式访问数据:

foreach (string statement in logItems.Select(x => x.Statement).Distinct()) 
{ 
    int count = logItems.Count(x => x.Statement == statement); 
    double percentage = count/logItems.Count(); 
    // any additional data 
} 

如果你想成为额外的高性能和花哨,你可以分析所有日志文件保存到数据库,并创建必要的数据查询。

+0

我会转发此技巧,但截至目前,我只能访问datagridview中存在的内容。另一种方法是从文本文件更新Datagridview。该代码在我的桌面上不可用。因此这个例子不会显示它。 – arvind 2012-03-27 06:22:06

+0

我可以使用这个类,并从Datagridview行生成列表,这有帮助吗?因为与行之后的速度相关的问题被填充。 – arvind 2012-03-27 06:23:16

+0

你总是可以将网格中的数据解析为类似人类的形式,并保留它:) – 2012-03-27 06:23:36

1

我有一些建议,

你可以使用LINQ使用这样你的循环过程。基本上linq使用了优化的查询,并且性能很好。

DataTable obj = new DataTable(); 
     obj.Columns.Add("count",typeof(Int32)); 
     DataRow dr = obj.NewRow(); 
     dr[0] = "10"; 
     obj.Rows.Add(dr); 

     DataRow dr1 = obj.NewRow(); 
     dr1[0] = "5"; 
     obj.Rows.Add(dr1); 

     obj.Columns.Add("countpercentage"); 

     int intCount = (from DataRow drrow in obj.Rows 
         select drrow.Field<int>("count")).Sum(); 

     (from DataRow drtemp in obj.Rows 
     select drtemp).ToList<DataRow>() 
     .ForEach(x => x.SetField<string>("countpercentage", ((x.Field<Int32>("count")*100)/intCount).ToString())); 
+0

为什么我们在这里计算平均值..(抱歉,但是我对linq的曝光是有限的,) – arvind 2012-03-27 07:05:27

+0

该领域是为了百分之几。现在更新。 – 2012-03-27 07:39:53

+0

它在两个地方的'from'关键字上生成错误,>>'System.Data.DataRowCollection'不包含'Cast'的定义 – arvind 2012-03-27 07:54:36