C#字符串格式化的C++实现
2017-09-13 15:56
260 查看
概要
C#字符串格式化的C++实现的步骤
原因
之所以做这个实现,是因为避免因为格式化导致的运行时错误
C#的完整格式化信息可以参考itjeff的这篇文章
先做个简化版的,支持{0},{1},{2}等等,不支持大括号里面的详细格式化语法
第一步,收集格式化参数
定义一个SArgument的轻量级类,封装各个基本类型的构造函数
如SArgument(int);
SArgument(const char*);
SArgument(float);
SArgument(double);
…(省略)
第二步,扫描解析
扫描并解析格式化字符串中的{0}模板
struct ReplacePoint{
int index; // argument index
int offset; // in m_buffer;
int length; // {\d+}的长度
};
一个结构体ReplacePoint表示出现的格式化{\d+}的基本信息,后续可以增加详细的格式化信息
最终得到ReplacePoint数组
第三步,字符串转化
根据SArgument的原始类型信息以及ReplacePoint格式化信息,将其转化为字符串
第四步,字符串合并替换
针对每个ReplacePoint,将格式化字符串中前面的原始内容拷贝
然后将其对应的SArgument参数产生的字符串拷贝
优点
1.类型信息静态捕捉:通过SArgument的各种构造函数抓捕,是否支持,编译时刻即可发现;
2.使用简单:使用的时候不用关心格式化,也不用关心格式化是否错误
原生的sprintf系列函数,写错了,就是运行时错误.
3.多个绑定:可支持如{0},{0},同一个参数可出现若干次
潜在的优点
这个模式,对**
全异步的超高性能日志:进入公司后就做的一个日志库,类似log4j2,当初没有c++版本,就考虑自己打造.没有参考其设计,完全自己按照极速来设计(后续会写这个方面的博文)
**非常友好
性能可以达到调用花费2-3us(微秒)
知识点:
如何为_vsnprintf_s_l定制化参数?
将每个参数前后衔接的放在一块内存中,模拟调用栈的参数内存,然后将此地址作为最后一个参数调用即可;
使用范例
char buf[128] = { 0 };
int len=FMTBUF(buf, “{0}-{1}-{2},{2}-{3}”, “Hello World!”, 10.0f, 11.0f, “45151515555555”);
最终buf内容如下:
“Hello World!-10.000000-11.000000,11.000000-45151515555555”
len为57
性能对比
FMTBUF(buf, “{0}-{1},{2}-{3}”, “Hello World!”, 10.0f, 11.0f, “45151515555555”);
_snprintf_s(buf, sizeof(buf), _TRUNCATE, “%s-%f,%f-%s”, “Hello World!”, 10.0f, 11.0f, “45151515555555”);
经过测试,非优化版,第一个性能是第二个的2倍,优化版,第一个是第二个的4倍
C#字符串格式化的C++实现的步骤
原因
之所以做这个实现,是因为避免因为格式化导致的运行时错误
C#的完整格式化信息可以参考itjeff的这篇文章
先做个简化版的,支持{0},{1},{2}等等,不支持大括号里面的详细格式化语法
第一步,收集格式化参数
定义一个SArgument的轻量级类,封装各个基本类型的构造函数
如SArgument(int);
SArgument(const char*);
SArgument(float);
SArgument(double);
…(省略)
第二步,扫描解析
扫描并解析格式化字符串中的{0}模板
struct ReplacePoint{
int index; // argument index
int offset; // in m_buffer;
int length; // {\d+}的长度
};
一个结构体ReplacePoint表示出现的格式化{\d+}的基本信息,后续可以增加详细的格式化信息
最终得到ReplacePoint数组
第三步,字符串转化
根据SArgument的原始类型信息以及ReplacePoint格式化信息,将其转化为字符串
第四步,字符串合并替换
针对每个ReplacePoint,将格式化字符串中前面的原始内容拷贝
然后将其对应的SArgument参数产生的字符串拷贝
优点
1.类型信息静态捕捉:通过SArgument的各种构造函数抓捕,是否支持,编译时刻即可发现;
2.使用简单:使用的时候不用关心格式化,也不用关心格式化是否错误
原生的sprintf系列函数,写错了,就是运行时错误.
3.多个绑定:可支持如{0},{0},同一个参数可出现若干次
潜在的优点
这个模式,对**
全异步的超高性能日志:进入公司后就做的一个日志库,类似log4j2,当初没有c++版本,就考虑自己打造.没有参考其设计,完全自己按照极速来设计(后续会写这个方面的博文)
**非常友好
性能可以达到调用花费2-3us(微秒)
知识点:
如何为_vsnprintf_s_l定制化参数?
将每个参数前后衔接的放在一块内存中,模拟调用栈的参数内存,然后将此地址作为最后一个参数调用即可;
使用范例
char buf[128] = { 0 };
int len=FMTBUF(buf, “{0}-{1}-{2},{2}-{3}”, “Hello World!”, 10.0f, 11.0f, “45151515555555”);
最终buf内容如下:
“Hello World!-10.000000-11.000000,11.000000-45151515555555”
len为57
性能对比
FMTBUF(buf, “{0}-{1},{2}-{3}”, “Hello World!”, 10.0f, 11.0f, “45151515555555”);
_snprintf_s(buf, sizeof(buf), _TRUNCATE, “%s-%f,%f-%s”, “Hello World!”, 10.0f, 11.0f, “45151515555555”);
经过测试,非优化版,第一个性能是第二个的2倍,优化版,第一个是第二个的4倍
相关文章推荐
- C#中使用IFormattable实现自定义格式化字符串输出示例
- C# IFormattable接口,实现自定义的字符串格式化方法
- 编写高质量代码改善C#程序的157个建议[为类型输出格式化字符串、实现浅拷贝和深拷贝、用dynamic来优化反射]
- MessageFormat对象实现格式化字符串输出,类似C#中的string.format方法
- 编写高质量代码改善C#程序的157个建议[为类型输出格式化字符串、实现浅拷贝和深拷贝、用dynamic来优化反射]
- 在C++中实现类似C#的字符串格式功能
- MessageFormat对象实现格式化字符串输出,类似C#中的string.format方法
- C# 格式化字符串的实现代码
- 判断一个字符串是否全是数字的多种方法及其性能比较(C#实现)
- C#中的字符串格式化
- C# 格式化字符串 String.Format (http://blog.soease.com/andy/)
- C、C++、Java和C#的源代码自动格式化工具:Artistic Style
- C#中实现字符串表达式计算
- C#中利用正则表达式实现字符串搜索
- C#实现将汉字与英文字符混和字符串中的汉字转换为拼音
- C#从文本文件(*.txt)中读取带有汉字的格式化的字符串
- C#中利用正则表达式实现字符串搜索[转]
- C#中利用正则表达式实现字符串搜索
- javascript 实现类似C#中字符串的Trim()方法
- 用C#实现基于查寻字符串的文件行查询器(3)-设计与实现