NSLog效率低下的原因及尝试lldb断点打印Log

ATGM332D模块串口配置保姆级教程:从9600波特率到NMEA数据过滤,一次搞定 本文提供ATGM332D模块串口配置的详细教程,涵盖从基础硬件连接到高级NMEA数据过滤的全过程。内容包括波特率优化、数据输出频率调整、NMEA语句过滤等实用技巧,帮助开发者快速掌握GNSS模块配置,提升定位系统性能。 阅读详情

NSLog效率低下的原因及尝试lldb断点打印Log


原文地址:http://blog.sunnyxx.com/2014/04/22/objc_dig_nslog/

我是前言

打Log是我们debug时最简单朴素的方法,NSLog对于objc开发就像printf对于c一样重要。但在使用NSLog打印大量Log,尤其是在游戏开发时(如每一帧都打印数据),NSLog会明显的拖慢程序的运行速度(游戏帧速严重下滑)。本文探究了一下NSLog如此之慢的原因,并尝试使用lldb断点调试器替代NSLog进行debug log。

小测试

测试下分别使用NSLog和printf打印10000次耗费的时间。CFAbsoluteTimeGetCurrent()函数可以打印出当前的时间戳,精度还是很高的,于是乎测试代码如下:

CFAbsoluteTime startNSLog = CFAbsoluteTimeGetCurrent();
for (int i = 0; i < 10000; i++) {
    NSLog(@"%d", i);
}
CFAbsoluteTime endNSLog = CFAbsoluteTimeGetCurrent();

CFAbsoluteTime startPrintf = CFAbsoluteTimeGetCurrent();
for (int i = 0; i < 10000; i++) {
    printf("%d\n", i);
}
CFAbsoluteTime endPrintf = CFAbsoluteTimeGetCurrent();

NSLog(@"NSLog time: %lf, printf time: %lf", endNSLog - startNSLog, endPrintf - startPrintf);

这个时间和机器肯定有关系,只看它们的差别就好。为了全面性,尝试了三种平台:

NSLog time: 4.985445, printf time: 0.084193 // mac
NSLog time: 5.562460, printf time: 0.019408 // 模拟器
NSLog time: 10.471490, printf time: 0.090503 // 真机调试(iphone5)

可以发现,在mac上(模拟器其实也算是mac吧)速度差别达到了60倍左右,而真机调试甚至达到了离谱的100多倍。

探究原因

* ASL

ASL是个啥?从官方手册上,或者从终端执行man 3 asl都可以看到说明:

These routines provide an interface to the Apple System Log facility. They are intended to be a
replacement for the syslog(3) API, which will continue to be supported for backwards compatibility.

大概就是个系统级别的log工具吧,syslog的替代版,提供了一系列强大的log功能。不过一般我们接触不到,NSLog就对它提供了高层次的封装,如这篇文档所提到的:

You can use two interfaces in OS X to log messages: ASL and Syslog. You can also use a number of higher-level approaches such as NSLog. However, because most daemons are not linked against Foundation or the Application Kit, the low-level APIs are often more appropriate

一些底层相关的守护进程(deamons)不会link如Foundation等高层框架,所以asl用在这儿正合适;而对于应用层的用NSLog。

在CocoaLumberjack的文档中也说了NSLog效率低下的问题:

NSLog does 2 things:
* It writes log messages to the Apple System Logging (asl) facility. This allows log messages to show up in Console.app.
* It also checks to see if the application’s stderr stream is going to a terminal (such as when the application is being run via Xcode). If so it writes the log message to stderr (so that it shows up in the Xcode console).
To send a log message to the ASL facility, you basically open a client connection to the ASL daemon and send the message. BUT - each thread must use a separate client connection. So, to be thread safe, every time NSLog is called it opens a new asl client connection, sends the message, and then closes the connection.

意识大概是说,NSLog会向ASL写log,同时向Terminal写log,而且同时会出现在Console.app中(Mac自带软件,用NSLog打出的log在其中全部可见);不仅如此,每一次NSLog都会新建一个ASL client并向ASL守护进程发起连接,log之后再关闭连接。所以说,当这个过程出现N次时,消耗大量资源导致程序变慢也就不奇怪了

* 时间和进程信息

主要原因已经找到,还有个值得注意的问题是NSLog每次会将当前的系统时间,进程和线程信息等作为前缀也打印出来,如:


2012-34-56 12:34:56.789 XXXXXXXX[36818:303] xxxxxx

当然这些也可能是作为ASL的参数创建的,但不论如何,一定是有消耗的(虽然这个prefix十有八九不是我们需要的看到的)

如何是好

NSLog有这样的消耗问题,那该怎么办呢?

拒绝残留的Log。现在项目都是多人共同开发,我们应该只把Log作为错误日志或者重要信息的日志使用,commit前请把自己调试的log去掉(尤其是在循环里写log的小伙伴,简直不能一起快乐的玩耍了)
release版本中消除Log。debug归debug,再慢也不能波及到release版本,用预编译宏过滤下就好。
是时候换个Log系统了,如CocoaLumberjack,自建一个简单的当然也挺好(其实为了项目需要自己也写了个小log系统,实现可以按名字和级别显示log和一些扩展功能,以后有机会分享下)
不过个人认为debug时最好还是用调试器进行调试(尤其是只需要知道某个变量值的时候)

尝试使用断点+lldb调试器打Log

关于强大的lldb调试器用一个专题来讲都是应该,现在只了解一些皮毛,不过就算皮毛的功能也可以替代NSLog这种方法进行调试了,重要的一点是:使用断点log不需要重新编译工程,况且和Xcode已经结合的很好,在此先只说打Log这件事。

简单断点+po(p)

断点时可以在xcode的lldb调试区使用po或p命令打印对象或变量,对于当前栈帧中引用到的变量都是可见的,所以说假如只是看一眼某个对象运行到这儿是不是存在,是什么值的话,设个断点就够了,况且IDE已经把这个功能集成,鼠标放变量上就可以了。

lldb一些常用调试技巧可以这篇入门教程

Condition和Action断点

断点不止能把程序断住,触发时也按一定条件,而且可以执行(一个或多个)Action,在断点上右键选择Edit Breakpoint,弹出的断点设置中可以添加一些Action:

其中专门有一项就是Log Message,做个小测试:

for (int i = 0; i < 10; i++) {
    // break point here
}

设置断点后编辑断点:

输入框下面就有支持的格式,表达式(或变量)可以使用@exp@这种格式包起来。于是乎输出:

break at: 'main()',  count: 4, sunnyxx says : 3
break at: 'main()',  count: 5, sunnyxx says : 4
break at: 'main()',  count: 6, sunnyxx says : 5

正如所料。
更多的调试技巧还需要深入研究,不过可以肯定的是,比起单纯的使用NSLog,使用好的工具可以让我们debug的效率更高

总结

  • NSLog耗费比较大的资源
  • NSLog被设计为error log,是ASL的高层封装
  • 在项目中避免提交commit自己的Debug log,release版本更要注意去除NSLog,可以使用自建的log系统或好用的log系统来替代NSLog
  • debug不应只局限于log满天飞,lldb断点调试是一个优秀的debug方法,需要再深入研究下

References

https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/asl.3.html
http://theonlylars.com/blog/2012/07/03/ditching-nslog-advanced-ios-logging-part-1/
http://www.cimgf.com/2012/12/13/xcode-lldb-tutorial/

把事务数据变成可分析数据:用 ABAP CDS 构建 Cube View 与 Query View,并拆解 OData 取数的底层路径 ABAP CDS分析建模:Cube与Query视图的实践解析 本文探讨了ABAP CDS分析建模中Cube View与Query View的核心区别与应用场景: 架构定位 Cube View作为分析型数据源,定义维度和度量的基础语义 Query View作为消费投影,控制查询可见字段和聚合逻辑 关键实现 通过@Analytics.dataCategory: #CUBE声明分析数据源 使用@DefaultAggregation确保指标口径一致性 @Analytics.query: true启用分析引擎特性 运 阅读详情

相关推荐

S32DS3.5图形化配置实战:从零构建S32K144通信接口工程

本文详细介绍了如何使用S32DS3.5图形化配置工具从零构建S32K144通信接口工程。通过实战演示引脚配置、时钟树设置、SPI接口搭建等关键步骤,帮助开发者快速掌握NXP S32K系列开发技巧,提升嵌入式开发效率。特别针对S32DS3.5版本的新特性进行了深度解析,包括智能代码生成和调试优化方法。

weixin_26834815的博客 199

熟练使用 LLDB,让你调试事半功倍

LLDB是Xcode默认的调试器,它与LLVM编译器一起,带给我们更丰富的流程控制和数据检测的调试功能。平时用Xcode运行程序,实际走的都是LLDB。熟练使用LLDB,可以让你debug事半功倍。 LLDB基础知识 LLDB控制台 Xcode中内嵌了LLDB控制台,在Xcode中代码的下方,我们可以看到LLDB控制台。 LLDB控制台平时会输出一些log信息。如果我们想输入命令

Ji晶晶的博客 5889

性能测试软件(LR12) 具体汉化(中文)方法

LoadRunner 12 的下载及安装详细过程请参考:https://blog.csdn.net/xiao66guo/article/details/105465854 1、在LoadRunner文件中找到 Setup.exe 可执行文件,并以管理员的身份运行: C盘 —> Temp—>HP LoadRunner 12.02 Community Edition—> D...

多谢大人光临寒舍,请随便看看,喝口茶吧 ☕️☕️☕️ 1992

iOS调试-通过lldb断点来打印log

相信还有很多人和我一样,当调试时想要查看某个参数的值的时候,会在代码中用log打印,然后重新运行。当log多了后,常常容易搞乱,而且总是重新运行、调试完删除log都很费事。这里介绍通过lldb来增加调试效率。        调试中我们经常需要打断点,当程序运行到断点时,程序会暂停,此时控制台会出现 (lldb)        这就表示我们可以在控制台里输入lldb指令进行操作(Xcode5

树深时见鹿 1725

如何适配自定义激光雷达数据到LIO-SAM:解决ring和time参数缺失问题

本文详细解析了如何将非标准激光雷达(如速腾、Livox)适配到LIO-SAM框架中,重点解决ring和time参数缺失问题。提供了从源码修改到通用适配中间件的多层级解决方案,并包含实机测试与性能调优指南,帮助开发者高效完成雷达数据适配。

weixin_42551227的博客 421

新手避坑指南:HT7036计量芯片SPI读取电压的完整流程(从复位到校准)

本文详细介绍了HT7036计量芯片的SPI读取电压完整流程,从硬件准备到校准设置,重点解析了复位引脚处理、SPI通信配置、芯片初始化及数据处理等关键步骤。针对常见问题如晶振焊接、SPI时序错误等提供实用解决方案,帮助开发者高效完成电压测量与校准。

weixin_30070339的博客 326

线程里执行输出耗时

经过测试,线程里执行了调试输出,由于输出数据有几Kbyte,最后发现非常耗时。 发现花了几秒。。。 long beforeSystemOutTime = System.currentTimeMillis(); System.out.print("read:\n"); for (int j=0;j<buffs.length;j++) {  System.out.print(buffs[

raining_heart的专栏 529

自制JS某课脚本

根据实际需求自制网页讯网刷题脚本,绕过人脸,弹窗,答题,实现自动化运行

2301_81243054的博客 3458

iOS 函数耗时测试

转载自:http://blog.csdn.net/kut00/article/details/8032882 CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();   // do something    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();    NSLog(@"time 

antjumper的专栏 1805

CMOS图像传感器系列--(四)HDR之LOFIC技术

CMOS图像传感器HDR技术之LOFIC解析 LOFIC(横向溢出积分电容器)技术是当前高动态范围成像的重要方案,通过在像素光电二极管旁设置高密度电容器收集溢出电荷,有效保留高光细节。该技术采用特殊像素结构,通过skim level触发电荷转移,实现单帧HDR成像。然而LOFIC存在显著局限性:高光区域噪声明显且难以消除,动态范围拓展不均衡(主要优化亮部),需复杂MIM工艺导致成本升高。为应对挑战,行业提出混合方案(如结合DCG技术)和工艺改进方向。OmniVision最新车载传感器OX08D10就采用了L

AIoT深度探索者 | 嵌入式系统架构师 深耕物联网(IoT)与人工智能(AI)融合技术,聚焦​​边缘计算、图像开发、低功耗通信协议​​,致力于智能硬件,关注我获取最新技术文章信息与海量资源~ 5788

PCL 点云八叉树射线相交

PCL 点云八叉树射线相交

dayuhaitang1的博客 850

NSLog效率低下的原因以及NSLog宏定义

我是前言 打Log是我们debug时最简单朴素的方法,NSLog对于objc开发就像printf对于c一样重要。但在使用NSLog打印大量Log,尤其是在游戏开发时(如每一帧都打印数据),NSLog会明显的拖慢程序的运行速度(游戏帧速严重下滑)。本文探究了一下NSLog如此之慢的原因,并尝试使用lldb断点调试器替代NSLog进行debug log。 小测试 测试下分别使

天方夜歌的博客 1723

【架构】-- StarRocks 和 Doris 介绍与选型建议

查询性能 | ✅ 高性能,支持向量化执行和 CBO 优化器 | ✅ 高性能,优化的查询引擎 |- **实时性要求高**:如果业务对数据的实时性要求较高,建议选择 **StarRocks**,其在实时数据处理和低延迟查询方面表现优越。- **复杂查询需求**:对于需要处理复杂多表关联查询的场景,两者均可胜任,需根据具体性能测试结果进行选择。

欢迎来到我的博客,一起探索代码里的世界! 1831

NSLog,LLDB, Breakpoint,EXC_BAD_ACCESS,Address Sanitizer ,iOS开发之Xcode常用调试技巧总结

一、Xcode调试技巧之:NSLog 上面也提到了,在我们日常的开发过程中最常见的Debug方式就是打Log。而在OC语言中,打Log是采用NSLog方法。但是NSLog效率低下,具体原因可以看这篇博客(《NSLog效率低下的原因及尝试lldb断点打印Log》)。所以在平时的开发过程中,能不打Log就不打Log。实在想打Log网上也有对NSLog的一些优化方法,可以阅读王巍的《宏定义的黑魔法

viiimaus的博客 1544

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

NSLog效率低下的原因

转自sunnyxx的技术博客   前言 打Log是我们debug时最简单朴素的方法,NSLog对于objc开发就像printf对于c一样重要。但在使用NSLog打印大量Log,尤其是在游戏开发时(如每一帧都打印数据),NSLog会明显的拖慢程序的运行速度(游戏帧速严重下滑)。本文探究了一下NSLog如此之慢的原因,并尝试使用lldb断点调试器替代NSLog进行debug log。

chengjiaming00的专栏 616

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

iOS开发之Xcode常用调试(Debug)技巧

一、Xcode 调试技巧之:NSLog2、Xcode调试技巧之:LLDB三、Xcode调试技巧之:断点调试(breakpoint)3.1 Breakpoint(断点)调试(1) Name 和 Condition(2) Ignore(3) action6.Sound参考资料。

yunfeihope的博客 8498

iOS开发之Xcode常用调试技巧总结,NSLog,LLDB, Breakpoint,EXC_BAD_ACCESS,Address Sanitizer

一、Xcode调试技巧之:NSLog 上面也提到了,在我们日常的开发过程中最常见的Debug方式就是打Log。而在OC语言中,打Log是采用NSLog方法。但是NSLog效率低下,具体原因可以看这篇博客(《NSLog效率低下的原因及尝试lldb断点打印Log》)。所以在平时的开发过程中,能不打Log就不打Log。实在想打Log网上也有对NSLog的一些优化方法,可以阅读王巍的《宏定义的黑魔法

zhonggaorong的专栏 2933

再见了NSLog

本文原文发表自我的【自建博客】,cnblogs同步发表,格式未经调整,内容以原博客为准 我是前言 打Log是我们debug时最简单朴素的方法,NSLog对于objc开发就像printf对于c一样重要。但在使用NSLog打印大量Log,尤其是在游戏开发时(如每一帧都打印数据),NSLog会明显的拖慢程序的运行速度(游戏帧速严重下滑)。本文探究了一下NSLog如此之慢的原因,尝试使用lldb...

weixin_30767835的博客 308

iOS开发之Xcode常用调试(Debug)技巧总结

一、Xcode调试技巧之:NSLog上面也提到了,在我们日常的开发过程中最常见的Debug方式就是打Log。而在OC语言中,打Log是采用NSLog方法。但是NSLog效率低下,具体原因可以看这篇博客(NSLog效率低下的原因及尝试lldb断点打印Log)。所以在平时的开发过程中,能不打Log就不打Log。实在想打Log网上也有对NSLog的一些优化方法,可以阅读王巍的《宏定义的黑魔法 - 宏菜鸟

hbblzjy的博客 8153

Xcode调试技巧

一、Xcode调试技巧之:NSLog上面也提到了,在我们日常的开发过程中最常见的Debug方式就是打Log。而在OC语言中,打Log是采用NSLog方法。但是NSLog效率低下,具体原因可以看这篇博客(《NSLog效率低下的原因及尝试lldb断点打印Log》)。所以在平时的开发过程中,能不打Log就不打Log。实在想打Log网上也有对NSLog的一些优化方法,可以阅读王巍的《宏定义的黑魔法 - 宏...

王正魁 1225

iOS开发之Xcode常用调试技巧总结

转载http://www.cocoachina.com/ios/20161102/17884.html   本文为投稿文章,作者:杨社兵 最近在面试,面试过程中问到了一些Xcode常用的调试技巧问题。平常开发过程中用的还挺顺手的,但你要突然让我说,确实一脸懵逼。Debug的技巧很多,比如最常见的方式是打个Log,在一些工程中处处可见NSLog。还有就是打断点的Debug方式等。诸如此类,下面...

chqj_163的专栏 220
上一篇: metal简介
下一篇: ObjC和JavaScript的交互,在恰当的时机注入对象
Philm_iOS
博客等级 码龄8年 74粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值