扫地老太太
据说在每一个互联网公司里,都有一个扫地的老太太。很偶然地,当她经过一个程序员的身边,扫一眼屏幕上的代码,会低声提醒对方说:小心,栈溢出了…
别看这是一个笑话,我那天真的遇上了!
只不过扫地老太太变成了前端工程师…
那天我在优化一个作业,里面有大批量的数据,为了监控我 Console.WriteLine
了。
然后前端工程师说:喂,不要用那么多的控制台输出,会影响性能的!
什么?控制台输出会影响性能?
我的三观瞬间崩塌了…
测试性能
我还是不相信这个残酷的现实,所以决定自己测试一下…
class Program
{
private static readonly ILog log = LogManager.GetLogger (typeof(Program));
private const int TestTimes = 10000;
static void Main (string[] args)
{
var a = NoWriteLine ();
var b = WriteLine ();
var c = Log4NetDebug ();
var d = Log4NetError ();
var e = DebugWriteLine ();
Console.WriteLine ("没有输出:" + a);
Console.WriteLine ("有输出:" + b);
Console.WriteLine ("Debug输出:" + e);
Console.WriteLine ("Log4Net没有输出:" + c);
Console.WriteLine ("Log4Net有输出:" + d);
}
private static long NoWriteLine ()
{
var watcher = new Stopwatch ();
watcher.Start ();
for (var k = 0; k < TestTimes; k++) {
}
watcher.Stop ();
return watcher.ElapsedTicks;
}
private static long DebugWriteLine ()
{
var watcher = new Stopwatch ();
watcher.Start ();
for (var k = 0; k < TestTimes; k++) {
Debug.WriteLine (k);
}
watcher.Stop ();
return watcher.ElapsedTicks;
}
private static long WriteLine ()
{
var watcher = new Stopwatch ();
watcher.Start ();
for (var k = 0; k < TestTimes; k++) {
Console.WriteLine (k);
}
watcher.Stop ();
return watcher.ElapsedTicks;
}
private static long Log4NetDebug ()
{
var watcher = new Stopwatch ();
watcher.Start ();
for (var k = 0; k < TestTimes; k++) {
log.Debug (k);
}
watcher.Stop ();
return watcher.ElapsedTicks;
}
private static long Log4NetError ()
{
var watcher = new Stopwatch ();
watcher.Start ();
for (var k = 0; k < TestTimes; k++) {
log.Error (k);
}
watcher.Stop ();
return watcher.ElapsedTicks;
}
}
最终执行结果如下:
Debug:
没有输出:1103
有输出:792840
Debug输出:31345359
Log4Net没有输出:58874
Log4Net有输出:3511244
Release:
没有输出:934
有输出:635316
Debug输出:223
Log4Net没有输出:33297
Log4Net有输出:2246490
可以看到,一万次循环控制台输出,要消耗那么多时间!平均一次63毫秒。
对于我那个作业,5W 多次循环,每次循环多次控制台输出(大约5次),算下来竟然需要三个小时…
我的作业竟然浪费了三个小时在控制台输出上…
我的三观再次崩塌…
解决方案
我上面的测试中已经提供了多种解决方案了,总之千万别用控制台输出了!
第一种方案是 Debug.WriteLine
,Release 模式下不会有任何性能问题,但是控制台看不到输出!必须云星仔 VS 中才可以看到输出。
第二种方案是写一个自己的 WriteLine,然后可以用配置,或者 C# 条件编译使其在生产环境中不会消耗那么多时间。
第三种方案就是用 log4net 了,输出 Debug
,生产环境中配置成 INFO 及以上即可。
个人推荐 log4net 方案,可以对所有日志有全局的控制。
虽然也有所损耗,但是还是降了一个数量级的,除非你对性能要求非诚非常高。
本作品由 Dozer 创作,采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。