macro
宏只是在预处理器里进行文本替换,没有类型,不做任何类型检查,编译器可以对相同的字符串进行优化。只保存一份到 .rodata 段。甚至有相同后缀的字符串也可以优化,你可以用GCC 编译测试,"Hello world" 与 "world" 两个字符串,只存储前面一个。取的时候只需要给前面和中间的地址,如果是整形、浮点型会有多份拷贝,但这些数写在指令中。占的只是代码段而已,大量用宏会导致二进制文件变大。
宏定义和全局变量的区别
- 宏会在预处理阶段被替换,而全局变量是在运行时;
- 宏定义不分配内存,全局变量定义需要分配内存;
- 宏不区分数据类型,它本质上是一段字符,在预处理的时候被替换到引用的位置,而全局变量区分数据类型;
- 宏定义之后值是不能改变的,全局变量的值是可以改变的;
- 宏定义只有在定义所在文件,或引用所在文件的其它文件中使用。 而全局变量可以在工程所有文件中使用,只需在使用前加一个声明。
FOUNDATION_EXTERN
#if defined(__cplusplus)
#define FOUNDATION_EXTERN extern "C"
#else
#define FOUNDATION_EXTERN extern
#endif
由以上定义可以看出 FOUNDATION_EXTERN 是可以兼容 C++ 的 extern 的宏。
FOUNDATION_EXTERN NSString * Extern_S = @"sss";
#define Define_S @"sss"
{
NSString * s = @"tt";
CFTimeInterval begin = CACurrentMediaTime();
for (int i = 0; i < 10000; i++) {
if ([s isEqualToString:Define_S]) {
}
}
NSLog(@"%f", CACurrentMediaTime() - begin);
begin = CACurrentMediaTime();
for (int i = 0; i < 10000; i++) {
if ([s isEqualToString:Extern_S]) {
}
}
NSLog(@"%f", CACurrentMediaTime() - begin);
}
2019-09-09 16:06:04.849874+0800 Demo[86518:3255355] 0.000148
2019-09-09 16:06:04.850170+0800 Demo[86518:3255355] 0.000137
extern 比宏在字符串上的比较速度要快一些,因为 extern 直接比较指针地址,而宏是比较字符串是否相等。
__builtin_expect
这个其实是个函数,针对编译器优化的一个函数。
写代码中我们经常会遇到条件判断语句
if (今天是工作日) {
printf("好好上班");
}
else {
printf("好好睡觉");
}
CPU 读取指令的时候并非一条一条的来读,而是多条一起加载进来,比如已经加载了 if(今天是工作日) printf(“好好上班”); 的指令,这时候条件式如果为非,也就是非工作日,那么 CPU 继续把 printf(“好好睡觉”); 这条指令加载进来,这样就造成了性能浪费的现象。
__builtin_expect 的第一个参数是实际值,第二个参数是预测值。使用这个目的是告诉编译器 if 条件式是不是有更大的可能被满足。
likely 和 unlikely
解开这个宏后其实是对 __builtin_expect 封装,likely 表示更大可能成立,unlikely 表示更大可能不成立。
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
遇到这样的,if(likely(a == 0)) 理解成 if(a==0) 即可,unlikely 也是同样的。
fastpath 和 slowpath
跟上面也是差不多的,fastpath 表示更大可能成立,slowpath 表示更大可能不成立
#define fastpath(x) ((typeof(x))__builtin_expect(_safe_cast_to_long(x), ~0l))
#define slowpath(x) ((typeof(x))__builtin_expect(_safe_cast_to_long(x), 0l))
这两个理解起来跟 likely 和 unlikely 一样,只需要关注里面的条件式是否满足即可。
os_atomic_cmpxchg
其内部就是 atomic_compare_exchange_strong_explicit 函数,这个函数的作用是:第二个参数与第一个参数值比较,如果相等,第三个参数的值替换第一个参数的值。如果不相等,把第一个参数的值赋值到第二个参数上。
#define os_atomic_cmpxchg(p, e, v, m) \
({ _os_atomic_basetypeof(p) _r = (e); \
atomic_compare_exchange_strong_explicit(_os_atomic_c11_atomic(p), \
&_r, v, memory_order_##m, memory_order_relaxed); })
os_atomic_store2o
将第二个参数,保存到第一个参数
#define os_atomic_store2o(p, f, v, m) os_atomic_store(&(p)->f, (v), m)
#define os_atomic_store(p, v, m) \
atomic_store_explicit(_os_atomic_c11_atomic(p), v, memory_order_##m)
os_atomic_inc_orig
将 1 保存到第一个参数中
#define os_atomic_inc_orig(p, m) os_atomic_add_orig((p), 1, m)
#define os_atomic_add_orig(p, v, m) _os_atomic_c11_op_orig((p), (v), m, add, +)
#define _os_atomic_c11_op_orig(p, v, m, o, op) \
atomic_fetch_##o##_explicit(_os_atomic_c11_atomic(p), v, \
memory_order_##m)
UNAVAILABLE_ATTRIBUTE , __has_include
macro的更多相关文章
- FreeMarker学习(宏<#macro>的使用)
原文链接:https://my.oschina.net/weiweiblog/blog/506301?p=1 用户定义指令-使用@符合来调用 有两种不同的类型:Macro(宏)和transform( ...
- configure.ac:32: error: possibly undefined macro: AC_DEFINE
在ubuntu 下编译snappy时,在检查依赖关系时,处理autoconf的包时,在相关依赖包都已经安装的情况下,报如下错误,死活不过. configure.ac:32: error: possib ...
- 【freemaker】之自定义指令<#macro>
测试代码 @Test public void test07(){ try { root.put("name", "张三"); freemakerUtil.fpr ...
- C++ macro(宏)使用小结
谈起C++中的宏,我们第一个想到的应该就是“#define”,它的基本语法长得像这样: #define macroname(para1, para2, para3, ... ,paran) macro ...
- Macro and SQL
If you’ve developed anything in the supply chain area, you’ve most probably come across InventDimJoi ...
- The difference between macro and function I/Ofunction comparision(from c and pointer )
macro is typeless and execute faster than funtion ,becaus of the overhead of calling and returnning ...
- Cmockery macro demo hacking
/********************************************************************* * Cmockery macro demo hacking ...
- __KERNEL__ macro
转载:http://blog.csdn.net/kasalyn/article/details/17097639 The __KERNEL__ macro is defined because the ...
- 幾種方法實現C語言Macro for debug
1. #include <stdio.h> #include <stdlib.h> #define DEBUG 1 #ifdef DEBUG #define DEBUG_PRI ...
- jinja2 宏的简单使用总结(macro)
Table of Contents 1. 简介 2. 用法 3. 参数和变量 4. 注意事项 4.1. macro的变量只能为如下三种: 4.2. 和block的关系: 5. 参考文档 1 简介 ji ...
随机推荐
- oa办公系统快速开发工具,助力企业优化升级
随着互联网的快速发展.信息化 IT 技术的不断进步.移动互联新技术的兴起,不管是大的集团企业还是中小型企业,纸质化的办公模式已不能满足现有需求,构建oa平台,为员工提供高效的办公环境尤其重要. 我们先 ...
- 常见WAF绕过思路
WAF分类 0x01 云waf 在配置云waf时(通常是CDN包含的waf),DNS需要解析到CDN的ip上去,在请求uri时,数据包就会先经过云waf进行检测,如果通过再将数据包流给主机. 0x02 ...
- 黑客必学之“网页木马webshell”
摘要: 这节课,我们来了解一下网页的木马,首先我们了解网页木马之前,先来了解一下什么是一句话木马.小马和大马.什么是webshell首先简单说一下webshell,webshell简单来说就是黑客植入 ...
- 【读后感】《Java编程思想》~ 异常
[读后感]<Java编程思想>~异常 终于拿出压箱底的那本<Java编程思想>.这本书我年轻的时候就买了,但是翻过几页后就放弃了.没想到这两天翻了一下,真的有收获. 看了一下第 ...
- 玩转 .NET Core 3.0:逐浪CMS新版发布,建站更简单、网站更安全
2019年11月11日,在大家都忙于网上体会“双11 ”的热闹气氛的时候,逐浪CMS开发者团队正在做着新版本发布的最后工作.此次更新是基本于 .NET Core 3.0开发,也是全国首个基于 .NET ...
- C# 时间戳(TimeStamp)与时间(DateTime)的互相转换
什么是时间戳:时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数. 时间戳在线转换网址:https://tool.lu/ ...
- 在Centos系统中基于PowerDNS和Poweradmin自建域名解析服务器替代DnsPod
本文讲述了我在Centos 7系统(其他版本的Centos未尝试)中基于PowerDNS和poweradmin自建域名解析服务器替代DnsPod的过程.通过本文所述方法,可以建立权威域名解析服务器的m ...
- Natas30 Writeup(sql注入)
Natas30: 本关是一个登录页面,查看源码,可以发现关键代码. if ('POST' eq request_method && param('username') &&am ...
- Python3学习之路~10.2 协程、Greenlet、Gevent
一 协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切 ...
- Jenkins分布式构建与并行构建
Jenkins分布式构建与并行构建 jenkins的架构 Jenkins采用的是"master+agent(slave)"架构.Jenkins master负责提供界面.处理HTT ...