前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >编程小知识 之 杂记两则

编程小知识 之 杂记两则

作者头像
用户2615200
发布2020-06-02 10:53:53
3210
发布2020-06-02 10:53:53
举报
文章被收录于专栏:tkokof 的技术,小趣及杂念

本文简述了之前遇到的两则编程杂记

隐式字符串字面量合并

之前看到一段 C/C++ 代码:

代码语言:javascript
复制
void func(const char* str) {
    // implementation ...
}

func("string" "params");

代码定义了一个参数为字符串指针的函数 func,调用时却使用了 “string” “params” 这种字符串连写的方式(中间没有逗号分隔符),初看时我一直怀疑调用代码存在"笔误",甚至认为这种写法会引起编译错误,但实际上, func(“string” “params”) 这种调用方式是正确无误的.

因为在编译期,像 “string” “params” 这种连写的字符串字面量会被合并为单个字符串字面量,所以上面 func(“string” “params”) 的调用代码经过编译后其实等价于 func(“stringparams”),这种被称为 隐式字符串字面量合并 的特性有两个注意点:

  • 合并发生在编译期,所以合并对运行时性能没有影响
  • 合并仅针对字符串字面量

所以如果你尝试对字符串变量进行隐式合并,那么等待你的就是编译错误了:

代码语言:javascript
复制
void func(const char* str) {
    // implementation ...
}

const char* params = "params";
// error here ...
func("string" params);

隐式字符串字面量合并的一大作用就是方便我们分隔大段的字符串代码文本,之前我们一般都会使用 行接续符(\) 来分隔长字符串:

代码语言:javascript
复制
const char* long_long_str = "long\
long\
string";

这种方式比较繁琐,格式上也不美观,使用隐式字符串字面量合并的话则会改善很多:

代码语言:javascript
复制
const char* long_long_str = "long"
		                    "long"
                            "string";
更多参考

try … catch 效率之殇

之前简单用 C# 写了一些用于读取 excel 配置的代码,其中有段逻辑用于处理以下的功能需求:

excel 单元格中一般配置为整型值,但是也有情况会配置为字符串(譬如配置为"是",而"是"最终会被映射为 1(这种映射关系事先会有定义),总的来说,支持将整数值配置为字符串是为了方便配置人员进行更直观的配置)

相关(简化)代码如下:

代码语言:javascript
复制
var cellStr = getCellStr();
var cellNum = 0;

try
{
    // first try parse int
    cellNum = int.Parse(cellStr);
}
catch (...)
{
    // then try map str to int
    if (!TryMapCellStr(cellStr, out cellNum)) 
    {
        // config error    
    }
}

结果代码运行之后奇慢无比,简单看了一下 profile 发现消耗最大的就是这段 try … catch 代码,自己摸索了一番,大概确定了几点原因:

  • 首先, int.Parse 的效率不高,可以考虑使用 int.TryParse 或者根据项目情况定制自己的 Parse 代码.
  • 再者, 应该也是最根本的一点,就是运行使用的 excel 表格中有大量使用字符串定义的整数值,遂而不断触发 try … catch 进行调用栈的记录和回退(unwind)操作,一般程序可能对少量的 try … catch 性能消耗并不敏感,但是大量 try … catch 的性能消耗非常巨大.

知道了原因,上述代码的调整方法也就明了了,我们首先尝试字符串映射(用以规避在 catch 块中进行正常的程序流处理)即可(使用 int.TryParse 直接规避 try … catch 应该是更好的一种做法):

代码语言:javascript
复制
var cellStr = getCellStr();
var cellNum = 0;

try
{
    // first try map str to int
    if (!TryMapCellStr(cellStr, out cellNum)) 
    {
        // then try parse int
        cellNum = int.Parse(cellStr);
    }
}
catch (...)
{
    // config error
}
总结

try … catch 尽量不要用于正常的程序流控制

更多参考
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/05/31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 隐式字符串字面量合并
    • 更多参考
    • try … catch 效率之殇
      • 总结
        • 更多参考
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档