• C#字符串格式化的C++实现


    概要
    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倍

  • 相关阅读:
    java9新特性-9-语法改进:try语句
    10.04 FZSZ模拟Day1 总结
    10.03模拟总结
    HNOI2012 永无乡
    ZJOI2007 报表统计
    HNOI2004 宠物收养场
    HNOI2002 营业额统计
    Splay 区间反转
    Splay基本操作
    HEOI2016 树
  • 原文地址:https://www.cnblogs.com/dhqcl/p/7527489.html
Copyright © 2020-2023  润新知