【问题标题】:Optimization performance winform app优化性能winform app
【发布时间】:2011-08-17 10:58:43
【问题描述】:

有什么方法可以通过一些实用程序来提高我的应用程序的性能?我正在使用 .Net framework 3.5 用 C# 编写应用程序,它是显示日志文件的应用程序,其中包含多行(它们是大约 200MB 的文本文件),它可以有 500MB RAM 内存和大约 10 秒的加载时间。我可以降低其中一些性能吗?当然,它可以通过更好的代码来完成,但我看到了 NGEN、GAC 的一些东西……这对我的应用程序也有帮助吗?谢谢

编辑

日志文件示例:

110331 052205 4969 [DB] fbba246f-bbe8-43b0-b8ca-f53bb90e8b51 Q   SELECT GRAFIKON.ID,GRAFIKON.NADRAZENYGRAFIKONID,GRAFIKON.PLATNOSTOD,GRAFIKON.PLATNOSTDO,GRAFIKON.OBJEDNAVANIOD,GRAFIKON.OBJEDNAVANIDO,GRAFIKON.NAZEV,GRAFIKON.PROOBJEDNAVANI,GRAFIKON.ARCHIV,GRAFIKON.UZAVREN,GRAFIKON_0.Nazev,GRAFIKON_1.PlatnostOd FROM GRAFIKON LEFT OUTER JOIN GRAFIKON GRAFIKON_0 ON  GRAFIKON.NADRAZENYGRAFIKONID = GRAFIKON_0.Id LEFT OUTER JOIN GRAFIKON GRAFIKON_1 ON  GRAFIKON.NADRAZENYGRAFIKONID = GRAFIKON_1.Id WHERE (GRAFIKON.PROOBJEDNAVANI = 1)

110331 052205 6062 [DB] fbba246f-bbe8-43b0-b8ca-f53bb90e8b51 Q   0s 109ms

110331 052205 6375 [DB] acdbcdb6-aa3a-460a-a323-0be7c4512c14 Q   SELECT NASTAVENI.ID,NASTAVENI.KLIC,NASTAVENI.HODNOTA,NASTAVENI.INFO,NASTAVENI.SKUPINA,NASTAVENI.TEXTAREA FROM NASTAVENI WHERE (NASTAVENI.KLIC = 'ARTICLE_AFTER_OPEN')

110331 052205 6688 [DB] acdbcdb6-aa3a-460a-a323-0be7c4512c14 Q   0s 31ms

110331 052205 7625 [DB] 9fd6ec6b-4844-44fe-8367-26c580ca8493 Q   SELECT NASTAVENI.ID,NASTAVENI.KLIC,NASTAVENI.HODNOTA,NASTAVENI.INFO,NASTAVENI.SKUPINA,NASTAVENI.TEXTAREA FROM NASTAVENI WHERE (NASTAVENI.KLIC = 'GRAPHICON_CLOSED_SMS_TEXT')

110331 052205 7625 [DB] 9fd6ec6b-4844-44fe-8367-26c580ca8493 Q   < 15ms

110331 065945 6813 [DB] 6387c3a4-33a5-4dfd-92d3-f4a8d00c910d Q   SELECT GRAFIKON.ID,GRAFIKON.NADRAZENYGRAFIKONID,GRAFIKON.PLATNOSTOD,GRAFIKON.PLATNOSTDO,GRAFIKON.OBJEDNAVANIOD,GRAFIKON.OBJEDNAVANIDO,GRAFIKON.NAZEV,GRAFIKON.PROOBJEDNAVANI,GRAFIKON.ARCHIV,GRAFIKON.UZAVREN,GRAFIKON_0.Nazev,GRAFIKON_1.PlatnostOd FROM GRAFIKON LEFT OUTER JOIN GRAFIKON GRAFIKON_0 ON  GRAFIKON.NADRAZENYGRAFIKONID = GRAFIKON_0.Id LEFT OUTER JOIN GRAFIKON GRAFIKON_1 ON  GRAFIKON.NADRAZENYGRAFIKONID = GRAFIKON_1.Id WHERE (GRAFIKON.PROOBJEDNAVANI = 1)

110331 065945 7438 [DB] 6387c3a4-33a5-4dfd-92d3-f4a8d00c910d Q   0s 62ms

前12个数字是日期和时间(然后是ms我可以去掉),然后是模数,信息,Q作为查询,然后是下一个信息或时间执行需要多长时间。这是我的代码:

   private Record GetRecordFromString(string strWithRecord)
    {
        Record newRecord = new Record();
        try
        {
            if (strWithRecord.Length < 24)
            {
                newRecord.Prikaz = strWithRecord;
                return newRecord;
            }
            if(!CheckIfFirstCharsAreDateTime(strWithRecord))
            {
                newRecord.Prikaz = strWithRecord;
                return newRecord;
            }

            newRecord.Datum = ChangeDateFormat(strWithRecord.Substring(0, 6));
            newRecord.Cas = ChangeTimeFormat(strWithRecord.Substring(7, 6));
            strWithRecord = strWithRecord.Remove(0, 20);

            int tempInt = strWithRecord.IndexOf(']');
            newRecord.Modul = strWithRecord.Substring(0, tempInt);

            strWithRecord = strWithRecord.Remove(0, tempInt + 2);
            if (newRecord.Modul.StartsWith("DB"))
            {
                if (Char.IsUpper(strWithRecord[0]))
                {
                    newRecord.Informace = strWithRecord;
                }
                else
                {
                    tempInt = strWithRecord.IndexOf(' ');
                    newRecord.Informace = strWithRecord.Substring(0, tempInt);
                    strWithRecord = strWithRecord.Remove(0, tempInt + 1);

                    tempInt = strWithRecord.IndexOf(' ');
                    newRecord.Priznak = strWithRecord.Substring(0, tempInt);
                    strWithRecord = strWithRecord.Remove(0, tempInt + 1);

                    newRecord.Prikaz = strWithRecord;
                }
            }
            else
            {
                newRecord.Informace = strWithRecord;
            }
        }
        catch(Exception e)
        {
            MessageBox.Show(e.Message);
        }
        return newRecord;
    }

private bool CheckIfFirstCharsAreDateTime(string stringToCheck)
{
    if (!Char.IsNumber(stringToCheck[0]) || !Char.IsNumber(stringToCheck[1]) || !Char.IsNumber(stringToCheck[2]) || !Char.IsNumber(stringToCheck[3]) || !Char.IsNumber(stringToCheck[4]) || !Char.IsNumber(stringToCheck[5]) || !Char.IsWhiteSpace(stringToCheck[6]) || !Char.IsNumber(stringToCheck[7]) || !Char.IsNumber(stringToCheck[8]) || !Char.IsNumber(stringToCheck[9]) || !Char.IsNumber(stringToCheck[10]) || !Char.IsNumber(stringToCheck[11]) || !Char.IsNumber(stringToCheck[12]))
    {
        return false;
    }
    return true;

}

private string ChangeDateFormat(string strWithDate)
{
    try
    {
        if (String.IsNullOrEmpty(strWithDate))
            return "";
        char[] arrayOfChars = strWithDate.ToCharArray();
        strWithDate = arrayOfChars[4].ToString() + arrayOfChars[5].ToString() + "." + arrayOfChars[2].ToString() + arrayOfChars[3].ToString() + ".20" + arrayOfChars[0].ToString() + arrayOfChars[1].ToString();
    }
    catch (Exception exp)
    {
        MessageBox.Show(exp.Message);
    }
    return strWithDate;
}

    private string ChangeTimeFormat(string strWithTime)
    {

        if (String.IsNullOrEmpty(strWithTime))
            return "";
        strWithTime = strWithTime.Insert(2, ":");
        strWithTime = strWithTime.Insert(5, ":");

        return strWithTime;
    }

编辑2 Profiler file

【问题讨论】:

    标签: c# visual-studio-2008 .net-3.5


    【解决方案1】:

    NGEN 仅有助于 JIT 性能;现在,您可以尝试了,但考虑到您的情况,在我看来,您的 IO 性能受到了限制。我可以建议的最简单的“修复”是:安装更快的磁盘(SSD 或其他东西)。

    当然,您并没有显示究竟您是如何阅读文件的;我建议使用StreamReaderReadLine(),并且只读取您实际想要显示的数据

    【讨论】:

    • 我需要处理文件中的所有数据,因为我需要过滤它们并对它们和其他数据进行排序。我正在使用 StreamReader 和 ReadLine。这个应用程序不仅适合我,所以用更快的磁盘修复并不是最好的解决方案:)
    • @Bibo 很好,但是如果 IO 性能是瓶颈,除非您 减少 IO - 例如,通过更改文件格式。压缩(gzip 或其他东西)可能会有所帮助——它用 CPU 换取 IO——而且大多数现代机器都有足够的 CPU,这是一个净收益。
    • @Bibo - 它也可能是 在您的代码中 减慢它的速度(我们无法判断没有代码) - 但同样:NGEN 不是灵丹妙药对于错误的代码。
    • 我添加了将行更改为类 Record 的代码。您认为压缩有助于提高性能吗?你的意思是压缩原始文件?我无法更改原始文件,因为它是其他应用程序的输出。
    • @Bibo;我会跟踪行内的索引 - 但首先:你有profiled这个吗?
    【解决方案2】:

    用于加载时间的性能分析器和用于内存使用的内存分析器。

    http://www.red-gate.com/

    他们有工具和免费试用版。没什么可说的了,因为你的问题没有代码,所以回复没有代码:)

    【讨论】:

    • 这是数百行的代码,我希望它写得很好想把它弄下来。我用红门工具做了一些分析,但我不确定我能解决什么问题。如果我把它贴在某个地方,你能帮我吗?
    • 我添加了profiler文件,希望filefactory没问题。我也有带内存的文件,但它有 600MB
    • 是为了让你在这里发布慢代码,而不是 10Mb 的转储文件。
    【解决方案3】:

    关于如何加快 Winforms 应用程序加载时间,这篇文章可能对您有所帮助:

    Improving Application Startup Time

    如果您在加载时将整个 200MB 的文本文件加载到内存中,但是我不确定这会有多大帮助 - 您应该尝试找到一种方法来避免将大文件加载到内存中,但是如何做到这一点将完全取决于了解您的应用程序是如何工作的。

    【讨论】:

      【解决方案4】:

      如果您必须处理如此大的数据集,则必须考虑感知性能。例如,为什么不使用BackgroundWorker 组件在后台线程上完成所有工作,并使用它的 OnProgress 事件让用户知道它的进度。

      NGEN 和其他技巧只能带您到此为止(实际上并没有那么远)- 您必须意识到您需要一种不同的方法。

      【讨论】:

      • 我正在使用 BackgroundWorker,所以我有进度条,但我只想花越来越少的时间花在工作上,主要是减少使用的内存。
      • @Bibo,那么您必须考虑向用户显示的内容。他们真的需要一次查看 200MB 的信息吗?我打赌不会。归根结底,200MB 将占用 RAM 空间和时间来处理 - 你无法解决这个问题。您必须考虑采取不同的方法。
      • 我不需要一次全部显示,但我需要过滤、排序和滚动(我在 datagrid 中,正好在 c1flexgrid 中)。
      • 我现在明白了。我认为有两种方法。一种是将日志文件加载到某种类型的数据库中并从那里查询。让数据库引擎完成过滤/排序/分组/等所有艰苦的工作……第二种方法是使用虚拟化方法。如果我从 vb6 的日子里没记错的话,c1flexgrid 有一个虚拟模式,您可以在其中加载大量数据,但它只会加载需要的数据。
      猜你喜欢
      • 2013-03-17
      • 2016-05-14
      • 2011-10-17
      • 2014-01-08
      • 1970-01-01
      • 2017-06-02
      • 2013-03-31
      • 2018-07-19
      • 1970-01-01
      相关资源
      最近更新 更多