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 ...
随机推荐
- OpenCV读一张图片并显示
Java 版本: JavaCV 用OpenCV读一张图片并显示.只需将程序运行时的截图回复.如何安装配置创建项目编写OpenCV代码,可参考何东健课件和源代码或其他资源. package com.gi ...
- 读书笔记-《Mysql技术内幕》
MYSQL 技术内幕 Mysql体系 连接池组件 管理服务和工具 SQL接口 查询分析器 优化器 缓冲 插件式存储引擎 物理文件 存储引擎 InnoDB(默认引擎) 支持事务 行锁设计 多版本并发控制 ...
- GO - if判断,for循环,switch语句,数组的使用
1.if - else if - else的使用 package main import "fmt" func main() { // 1.简单使用 var a=10 if a== ...
- 基于python openOPC的监控页面一
笔者涉猎的工业领域项目遇到一个需求,需要把底层设备(表记)的状态和运行数据集中放到一个监控画面进行展示,数据需要在界面端实时进行刷新,类似网友的例子,如下图(侵删) 数据需要实时主动刷新,笔者基于多年 ...
- AWS EC2+Docker+JMeter构建分布式负载测试基础架构
目录 概述及范围 前提条件 Part 1: Local setup-本地配置 Part 2: Cloud端基础架构--Infrastructure 总结: 原文链接 @ 概述及范围 本文介绍有关如何使 ...
- zookeeper和dubbo安装与搭建(2)
Zookeeper+Dubbo安装与搭建(2) (原创:黑小子-余) 一.环境配置:zookeeper3.6.0 + dubbo3.5.4 + maven3.6.1 + jdk1.8 + tomcat ...
- Object-Oriented Programming Summary Ⅱ
电梯作业总结博客 17373492 电梯,多线程学习中的 "HelloWorld",早在大一就有所耳闻,以至于在坐电梯的时候就思考过:电梯需要怎么写呢? 0. 前言: 偶然的机会, ...
- .NET微服务从0到1:服务注册与发现(Consul)
目录 Consul搭建 基于Docker搭建Consul 基于Windows搭建Consul ServiceA集成Consul做服务注册 Ocelot集成Consul做服务发现 更多参考 Consul ...
- 盘点Linux运维常用工具(二)-web篇之nginx
1.nginx的概述 .nginx是一个开源的.支持高性能.高并发的WWW服务和代理服务软件 .是由俄罗斯人Igor Sysoev开发的,具有高并发.占用系统资源少等特性 .官网:http://ngi ...
- [NodeJS] async 和 await 的本质
绝大多数nodejs程序员都会使用 async 和 await 关键字,但是极少有人能真正弄明白 async 和 await 的原理.这篇文章将从零“构建”出 async 和 await 关 ...