ostringstream 多线程下性能问题探究

news2025/1/21 5:58:54

文章目录

  • 背景
  • 火焰图
  • ostringstream 的结构
  • 引用

背景

在实习过程中,有一个业务场景需要用到 ostringstream,但经过导师提醒,ostringstream 在多线程关系下,竞态消耗较大,但对于当前业务场景,每次操作,都有自己独立的 ostringstream,为什么还会有竞争关系存在呢?
https://chys.info/blog/2017-11-06-ostringstream-performance
在上面这篇文章初窥门径。

火焰图

用以测试的文件:就是建立20个线程,用stringstream做一下数据操作,对照组是 fmt::memory_buffer。
用火焰图进行观测
stringstream 版
image.png
image.png
可以看出 locale的构造函数和析构函数的占用是相对较高的,而采用 memorybuffer 的:
image.png
image.png
由此可以看出,stringstream 的调用时间,被 local 的构造析构函数拉长了,且对于数据的组装ostringtream 性能也是逊色于 fmt::memory_buffer,下面来分析原因。
locale 是什么

ostringstream 的结构

上面火焰图得到了原因,我们现在直接去锁定 local 这个结构在哪。
ostringstream 是 basic_ostringstream 的特化版本

typedef basic_ostringstream<char>    ostringstream;

之后就存在着一个继承关系
image.png
经过代码的阅读和排查,最终锁定在basic_ostream 的构造函数中,总体是一个这样的逻辑:
当一个 ostringstream被构造出来,首先在他的构造函数中会调用基类的构造函数

explicit basic_ostringstream(ios_base::openmode __wch = ios_base::out)
: basic_ostream<_CharT, _Traits>(&__sb_) // 这里
, __sb_(__wch | ios_base::out)
{ }

然后该基类的构造函数,会调用 init 方法,该方法继承自 ios_base

explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb)
{ this->init(__sb); }


void
ios_base::init(void* sb)
{
    __rdbuf_ = sb;
    __rdstate_ = __rdbuf_ ? goodbit : badbit;
    __exceptions_ = goodbit;
    __fmtflags_ = skipws | dec;
    __width_ = 0;
    __precision_ = 6;
    __fn_ = 0;
    __index_ = 0;
    __event_size_ = 0;
    __event_cap_ = 0;
    __iarray_ = 0;
    __iarray_size_ = 0;
    __iarray_cap_ = 0;
    __parray_ = 0;
    __parray_size_ = 0;
    __parray_cap_ = 0;
    ::new(&__loc_) locale;  // 关注这里
}

该 init 函数便与那个锁竞争有关。
该函数中,新建了一个 locale 变量,下面是该变量的析构和构造函数:

locale::locale()  _NOEXCEPT
: __locale_(__global().__locale_)
{
    __locale_->__add_shared(); // 原子性操作 该变量与 __shared_count 存在继承关系,
}

locale::~locale()
{
    __locale_->__release_shared(); // 原子性操作 该变量与 __shared_count 存在继承关系
}

且从上面火焰图可知,该类的变量__locale_ 的构造函数耗时也不小:

locale::__imp::__imp(const __imp& other)
: facets_(max<size_t>(N, other.facets_.size())),
name_(other.name_)
{
    facets_ = other.facets_;
    for (unsigned i = 0; i < facets_.size(); ++i)
        if (facets_[i])
            facets_[i]->__add_shared(); // 原子性操作
}

再因为由于每一个stringstream 的流式操作都是用相同的 locale ,因此在测试程序刚开始运行时,就会产生激烈的锁竞争因此影响性能。
而 memory_buffer 则是与 locale 无关,且数据组装部分实现也较为高效,故建议替代。
且在查阅资料后发现
由此观之,标准库中所有输入输出流,都存在着此问题。

引用

locale 是什么
http://blog.chinaunix.net/uid-27670726-id-3327314.html
https://blog.51cto.com/xqtyler/2058706

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/991274.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【美团3.18校招真题2】

大厂笔试真题网址&#xff1a;https://codefun2000.com/ 塔子哥刷题网站博客&#xff1a;https://blog.codefun2000.com/ 最多修改两个字符&#xff0c;生成字典序最小的回文串 提交网址&#xff1a;https://codefun2000.com/p/P1089 由于字符串经过修改一定为回文串&#x…

[Linux]动静态库

[Linux]动静态库 文章目录 [Linux]动静态库见一见库存在库的原因编写库模拟编写静态库模拟使用静态库模拟编写动态库模拟使用静态库 库的加载原理静态库的加载原理动态库的加载原理 库在可执行程序中的编址策略静态库在可执行程序中的编址策略动态库在可执行程序中的编址策略 见…

本地启动 Falcon-180B

本地启动 Falcon-180B 通过 Gradio 的 load 函数&#xff0c;我们可以在本地加载 HuggingFace 的 Spaces 上面的 demo。 那就运行 Falcon-180B 来试试吧。 创建 falcon_demo.py 文件&#xff0c; cat << EOF > falcon_demo.py import gradio as grdemo gr.load(&q…

小节3:数据类型

Python的数据类型包括&#xff1a;字符串&#xff08;str&#xff09;、整数&#xff08;int&#xff09;、浮点数&#xff08;float&#xff09;、布尔类型&#xff08;bool&#xff09;、空值类型&#xff08;NoneType&#xff09;、列表&#xff08;list&#xff09;、字典&…

Spring Cloud zuul与CloseableHttpClient连接池,TLS证书认证

前言 最近做项目&#xff0c;需要一个代理逻辑&#xff0c;实际上这种代理NGINX最好&#xff0c;但是有些额外功能的开发&#xff0c;NGINX就需要额外能力支持&#xff0c;比如lua脚本&#xff0c;常见的做法有kong&#xff0c;apisix等&#xff0c;据说apisix的性能较强&…

Python 03(循环语句)

Python03&#xff08;循环语句&#xff09; 文章目录 Python03&#xff08;循环语句&#xff09;一、while语句二、while实现猜数字三、while循环的嵌套while循环嵌套实例需求&#xff1a; 四、for循环1、什么 是for循环2、语法3、执行流程4、for循环的基本使用5、range()函数6…

光刻机的原理和技术路线概览

一、简介 集成电路产业被誉为现代“工业粮食”&#xff0c;引领未来科学技术产业革命的发展&#xff0c;带动世界前沿技术创新发展。 集成电路产业是社会发展的先导产业&#xff0c;主要包括半导体材料、装备、芯片制造、封装测试、电路设计等重要环节。 随着工业智能制造和电子…

OpenCV(三十):图像膨胀

1.图像膨胀原理 图像膨胀的原理是将一个结构元素&#xff08;也称为核或模板&#xff09;在图像上滑动&#xff0c;并将其与图像中对应位置的像素进行比较。如果结构元素的所有像素与图像中对应位置的像素都匹配&#xff0c;那么该位置的像素值保持不变。如果结构元素的任何一个…

Telnet

远程登录/管理 目录 1、什么是Telnet 2、Telnet工作原理 3、常见的Telnet使用场景 4、Telnet协议结构 5、Telnet工作流程 6、Telnet常见命令 6.1、[Huawei]user-interface ? 用户界面 6.2、[Huawei]user-interface vty ? 6.3、[Huawei-ui-vty0-4]? 6.4、[Huawei-…

软件测试技术题目大全【含答案】

请看下面 你的测试职业发展是什么?  测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&#xff0c;按如何做好测试工程师的要点去要求自己&#x…

buuctf crypto 【[AFCTF2018]Morse】解题记录

1.打开文件 2.摩斯密码解密 3.这个结果验证之后发现不对&#xff0c;猜测是16进制转字符 4.验证发现是对的

直方图均衡化原理

import numpy as np import cv2 hist, bins np.histogram(img, bins256, range(0, 256))# 计算累积分布函数&#xff08;CDF&#xff09; cdf np.cumsum(hist)# 归一化CDF&#xff1a; 归一化CDF以确保其范围在0到255之间 cdf_norm 255 * (cdf - cdf.min()) / (cdf.max()…

提词软件有哪些?了解一下这几个

提词软件有哪些&#xff1f;提词软件可以广泛应用于各种场景。除了在学习和工作中提高效率外&#xff0c;在日常生活中也有很多用处。例如&#xff0c;在进行演讲的时候&#xff0c;如果担心会因为紧张而忘词的话&#xff0c;就可以使用一些提词软件&#xff0c;将演讲词编辑进…

使用P5.js来制作一个快乐的小风车动画

p5.js简介 前一段时间偶然了解到一个觉得很好玩儿的东西p5.js,于是就去了解了一下&#xff0c;发现可以自己设计一些有趣的动画效果&#xff0c;设计出来的动画可以放置到页面当中&#xff0c;而且也是简单易学的。 下面是一段官方的介绍&#xff1a; p5.js是一个以 Processi…

0016Java程序设计-springboot幼儿园管理系统

摘 要目 录系统设计开发环境 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于幼儿园管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了幼儿园管理系统&a…

从JVM角度看继承

从JVM角度看继承 最近重读了周志明老师的《深入理解JAVA虚拟机》一书&#xff0c;看完大有收获&#xff0c;但仍对继承情况下对象内存布局有所疑惑&#xff0c;所以查阅资料&#xff0c;结合本书进行分析 参考文档&#xff1a; 【深入理解JVM】&#xff1a;Java类继承关系中…

算法训练营day45|动态规划 part07:完全背包 (LeetCode 70. 爬楼梯(进阶)、322. 零钱兑换、279.完全平方数)

文章目录 70. 爬楼梯(进阶)(求排列方法数)思路分析代码实现 322. 零钱兑换(求等于背包重量的最小物品数)思路分析代码实现思考总结 279.完全平方数 (求等于背包重量的最小物品数)思路分析代码实现 70. 爬楼梯(进阶)(求排列方法数) 题目链接&#x1f525; 假设你正在爬楼梯。需…

jquery jstree的懒加载

效果如下 使用jquery的jstree组件 1.前端准备工作 1.1引入jstree样式和js <link rel"stylesheet" href"/public/vendor/jstree/jstree.css"> <div id"departmentJstree"></div> <script src"/public/vendor/jstree…

Dominosa/数邻(2) | C++ | BFS

目录 一、Dominosa简介二、题目描述三、编程思路四、完整代码 一、Dominosa简介 Dominosa&#xff0c;中文名称为数邻&#xff0c;是一种棋盘游戏&#xff0c;基于骨牌的排列和匹配来进行。它是从骨牌游戏中发展而来的&#xff0c;在骨牌的基础上添加了一些规则和难度。具体的游…

canape中快速配置需要录制参数的技巧

以前在车里录制数据时&#xff0c;大量融合数据一个一个拖拽 &#xff0c;不仅慢&#xff0c;有时心不细的话&#xff0c;还会漏选、挑错。 用正则表达式的挑选方法&#xff0c;可以既快速又准确的挑出所需数据。 以下蓝色字体是操作方法&#xff1a; 正则表达式 示例&#xff…