【问题标题】:Estimate the memory usage in .NET (VS)估计 .NET (VS) 中的内存使用情况
【发布时间】:2009-12-19 02:25:57
【问题描述】:

我阅读了一篇关于字符串方法 "a" + b 与 string.Format("a{1}", b) 的性能的文章,并决定进行测试。

在 WinForms 应用程序中有我的代码(VS 2005,但对 2005/2008 都感兴趣)。

    private void button1_Click(object sender, EventArgs e)
    {
        Stopwatch stopwatch = new Stopwatch();

        stopwatch.Start();
        for (int i = 0; i < 10000; i++)
        {
            Console.Write("1" + 2 + "3" + 4 + "5");
        }
        stopwatch.Stop();
        Console.WriteLine("**********");
        Console.WriteLine("'A'+'B'+'C'... 10 000 elapsed: {0}", 
            stopwatch.Elapsed.ToString());
        Console.WriteLine("**********");
        stopwatch.Reset();

        stopwatch.Start();
        for (int i = 0; i < 10000; i++)
        {
            Console.Write(string.Format("1{0}3{1}5", 2, 4));
        }
        stopwatch.Stop();
        Console.WriteLine("**********");
        Console.WriteLine("string.Format((A)B(C)...) 10 000 elapsed: {0}", 
            stopwatch.Elapsed.ToString());
        Console.WriteLine("**********");

    }

在我的机器上输出如下:


12345123451234512345123451234512345123451234512345123451...

'A'+'B'+'C'... 10 000 已过:00:00:0 9.4217880


12345123451234512345123451234512345123451234512345123451...

string.Format((A)B(C)...) 10 000 已过:00:00:0 9.8507060


所以,时间几乎是一样的。

现在,我想知道我用了多少内存。有没有办法比较内存使用情况和 GarbageCollector 的工作?

我下载了一个试用版 .NET Memory Profiler...但也许有一种更简单(如上面的代码)的方法来检测两次迭代中消耗的内存?

谢谢。

【问题讨论】:

  • 您应该真正消除测试循环中的 Console.Write。输出速度相对较慢,而且很可能会出现瓶颈,而不是在字符串形成时出现瓶颈。
  • 只是为了备份它,我的机器上的第二个时间。带输出:0.5482043s。无输出:0.0098585s。

标签: .net visual-studio performance


【解决方案1】:

GC.GetTotalMemory 可能足够准确:

http://msdn.microsoft.com/en-us/library/system.gc.gettotalmemory.aspx

否则,您可以通过 System.Diagnostics.PerformanceCounter 使用 CLR GC 堆性能计数器。

【讨论】:

  • hm...你认为我应该在哪里调用 GC.GetTotalMemory
  • 也许在每 100 次迭代后进行一次,看看这是否能给你一个好的画面。如果您想要图表,只需启动性能监视器并添加 .Net GC 计数器。
【解决方案2】:

我的建议是……

我会在循环中取出 console.writeline,因为 Console.WriteLine 将它自己的观察者效应引入到经过的时间中。只需将其分配给变量或类似的。

你也可能没有给 String.Format 一个公平的休息......你不知道 GC 是否在你的两个循环之间运行。当您在第二个循环中时,GC 可能会启动,从而扭曲您的时间。或者它可能根本没有发挥作用。我会确定这一点,或者以相反的顺序运行测试。

一般来说,字符串是一种特殊情况。 .NET 中字符串的许多问题实际上来自于 windows 处理字符串的方式。我可以说的最好的方式是字符串不像其他对象那样干净,所以我可以做任何事情来避免创建比我需要的更多的字符串。当然,我们处理很多字符串,因为这就是我们所做的,所以我只谈论构建额外的字符串。

示例:使用 String.Format("select {0} from {1} where {2}",selectStmt, fromStmt, whereStmt) 从模板构建 SQL 命令似乎很酷,但保持选择你需要的常量或类似的,特别是如果你要经常解雇它们并一遍又一遍地构建相同的字符串。它也不太容易受到 SQL 注入的影响(此时不离题)。这只是举例,我并不是说你不应该使用 ORM 等。

查看http://blog.briandicroce.com/2008/02/04/stringbuilder-vs-string-performance-in-net/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-12
    • 2010-10-17
    • 1970-01-01
    • 2015-10-26
    • 2020-05-27
    • 2011-02-27
    • 1970-01-01
    • 2018-03-26
    相关资源
    最近更新 更多