本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/139200870
AWTK github gitee doc scons 类似RT-Thread
element github C++
Cross platfrom C++ GUI libraries,QT可替代方案。调试包
SDL GUI
cegui
创作不易, 小小的支持一下吧!


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/139200611
1 | #!/bin/sh |
1 | export DISPLAY=1:0 |


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/139184128
#include
class Base;
using BaseSp = std::shared_ptr
class Base
{
public:
explicit Base(int id) : ID(id) {}
int ID;
};
class Sorter
{
public:
virtual bool sort(const BaseSp &l, const BaseSp &r) { return true; }
};
using SorterSp = std::shared_ptr
class BaseNameSorter : public Sorter
{
public:
bool sort(const BaseSp &l, const BaseSp &r) override { return l->ID < r->ID; }
};
using BaseNameSorterSp = std::shared_ptr
class BaseDateSorter : public Sorter
{
public:
bool sort(const BaseSp &l, const BaseSp &r) override { return l->ID < r->ID; }
};
using BaseDateSorterSp = std::shared_ptr
class ShareSorter
{
public:
SorterSp sorter;
};
using ShareSorterSp = std::shared_ptr
using ShareSorterWp = std::weak_ptr
class SortBase
{
public:
explicit SortBase(BaseSp data, ShareSorterSp sorter) : base(data), m_sortDelegate(sorter) {}
bool operator<(const SortBase &other) const
{
bool isExpired = m_sortDelegate.expired();
auto delegate = m_sortDelegate.lock();
if (isExpired || !delegate || !delegate->sorter) {
assert(false);
return true;
}
return delegate->sorter->sort(base, other.base);
}
BaseSp base;
ShareSorterWp m_sortDelegate;
};
class Group
{
public:
std::set
ShareSorterSp m_sorter;
};
int main()
{
Group styleGroups; //数组组
ShareSorterSp shareSorter = std::make_shared
shareSorter->sorter = std::make_shared
styleGroups.m_sorter = shareSorter; //初始化组与子共享排序器
BaseSp base1 = std::make_shared
BaseSp base2 = std::make_shared
styleGroups.m_set.emplace(base1, styleGroups.m_sorter); //添加待排序数据
styleGroups.m_set.emplace(base2, styleGroups.m_sorter); //触发共享排序器
shareSorter->sorter = std::make_shared
BaseSp base3 = std::make_shared
styleGroups.m_set.emplace(base3, styleGroups.m_sorter);
return 0;
}
本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/139183985
std::ref
std::variant<double, bool, std::string> var; //替代union
**if(std::**holds_alternative
if(0 == var.index())
struct {
void operator()(int) { std::cout << “int!\n”; }
void operator()(std::string const&) { std::cout << “string!\n”; }
} visitor;
std::visit(visitor, var);

template
auto print_type_info(const T& t) {
if constexpr (std::is_integral
return t + 1;
} else {
return t + 0.001;
}
}
template
auto add(T x, U y) -> decltype(x+y) {
return x+y;
}
// sizeof… 不定参数个数
template<typename… Ts>
void magic(Ts… args) {
std::cout << sizeof…(args) << std::endl;
}
// 1. recursive parameter unpack
template
void printf1(T0 value) {
std::cout << value << std::endl;
}
template<typename T, typename… Ts>
void printf1(T value, Ts… args) {
std::cout << value << std::endl;
printf1(args…);
}
template<typename T, typename… Ts>
auto printf3(T value, Ts… args) {
std::cout << value << std::endl;
(void) std::initializer_list
std::cout << args << std::endl;
}(), value)…};
}
template<typename … T>
auto sum(T … t) {
return (t + …);
}
static std::mutex mtx;
std::lock_guardstd::mutex lock(mtx);
// pack a lambda expression that returns 7 into a std::packaged_task
std::packaged_task<int()> task([](){return 7;});
// get the future of task
std::future
std::thread(std::move(task)).detach();
std::cout << “waiting…”;
result.wait(); // block until future has arrived
// 限制参数是否满足指定用法
template
concept bool Stringable = requires(T a){
{a.to_string()} -> string;
};
void print(Stringable a){
std::cout << a.to_string() << std::endl;
}
struct Person {
double height, weight;
Person(double a, double b) : height(a), weight(b) {}
string to_string(){
return “weight: “+ std::to_string(weight) + “, height: “+ std::to_string(height);
}
};
Person p(57, 170.0);
print(p); // uses concept Stringable
1 | std::vector<int> datas{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; |
std::recursive_mutex 解决死锁
atomic 自带线程锁 fetch_add is +=, store is =, load is read, exchange读取并写入,compare_exchange_strong读取,比较是否相等,相等则写入
std::recursive_mutex 替换std::mutex解决同一线程死锁
std::shared_ptr
GitHub - parallel101/course: 高性能并行编程与优化 - 课件


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/139157864
class BaseStyle {
public:
enum ProperyID{
PROP_FONT_SIZE,
PROP_PARAGRAPH_INDENT
};
// virtual bool createLocalStyle();
virtual void setProperty(int type, void* val) = 0;
};
using BaseStyleSp = std::shared_ptr
class ShareData {
public:
ShareData(float fontSize): m_fontSize(fontSize){}
size_t hash() const { return std::hash
public:
float m_fontSize;
};
using ShareDataSp = std::shared_ptr
using ShareDataWp = std::weak_ptr
class ShareDocData {
public:
float paragraphIndent;
};
using ShareDocDataSp = std::shared_ptr
using ShareDocDataWp = std::weak_ptr
class ShareDataLRU {
public:
ShareDataLRU(): m_hitCount(0) {}
int m_hitCount;
};
#include
#include <unordered_map>
class ShareDataMergeManger{
class CharHash {
public:
std::size_t operator()(const ShareDataSp &sharedPtr) const {
if(!sharedPtr)
return 0;
return sharedPtr->hash();
}
};
class CharCmp {
public:
bool operator()(const ShareDataSp &selfPtr, const ShareDataSp &otherPtr) const {
if(selfPtr == otherPtr)
return true;
if(!selfPtr)
return false;
if(!otherPtr)
return false;
return selfPtr->hash() == otherPtr->hash();
}
};
public:
ShareDataSp allocCharData(const ShareDataSp charData) {
//if(manger.size() > 20000)
// clearUnUsed();
return std::make_shared
}
ShareDataSp addCacheCharData(const ShareDataSp& data) {
auto ret = manger.emplace(data, ShareDataLRU());
if(ret.second) { //新添加成功
return ret.first->first;
} else { //已存在,返回旧的
++ret.first->second.m_hitCount;
return ret.first->first;
}
}
ShareDataSp findCharData(const ShareDataSp& data) {
auto shareData = manger.find(data);
if(shareData == manger.end()) {
return nullptr;
}
else {
++shareData->second.m_hitCount; //查找次数+1,热度上升
return shareData->first;
}
}
void removeCharData(const ShareDataSp& data) {
manger.erase(data);
}
// 内存超过指定长度,自动清除未使用的区域
void clearUnUsed() {
for (auto iter = manger.begin(); iter != manger.end(); ) {
if(1 == iter->first.use_count())
iter = manger.erase(iter);
else
++iter;
}
}
public:
std::unordered_map<ShareDataSp, ShareDataLRU, CharHash, CharCmp> manger;
};
using ShareDataMergeMangerSp = std::shared_ptr
using ShareDataMergeMangerWp = std::weak_ptr
class LocalStyle : public BaseStyle {
public:
LocalStyle(ShareDataSp charData, ShareDocDataSp docData, const ShareDataMergeMangerSp& shareDataMergeManger):m_charData(shareDataMergeManger->addCacheCharData(charData)), m_docData(docData), m_shareDataMergeManger(shareDataMergeManger){
}
// ~LocalStyle() {
// if(m_shareDataMergeManger.expired()) {
// return;
// }
// auto allocManger = m_shareDataMergeManger.lock();
// if(!allocManger)
// return;
// if(2 == m_charData.use_count())
// allocManger->removeCharData(m_charData);
// }
void setFontSize(float size) {
m_charData->m_fontSize = size;
}
float fontSize() const {
return m_charData->m_fontSize;
}
private:
void setProperty(int type, void* val) override {
if(PROP_FONT_SIZE == type) {
auto newVal = *(float*)val;
auto useCout = m_charData.use_count();
if(fontSize() == newVal)
return;
if(useCout == 2 || useCout == 1) { //自己独占或与内存管理类共享数据
removeCache(); //更新hash,需先移除
} else {
detach(); //创建副本
}
setFontSize(newVal);// 改值
merge(); //缓存更新
}
}
void removeCache() {
auto allocManger = shareMemoryManger();
if(!allocManger)
return;
allocManger->removeCharData(m_charData); //先删除,key值hash不跟随联动,暂无法解决性能损耗
}
void detach() {
auto allocManger = shareMemoryManger();
if(!allocManger)
return;
m_charData = allocManger->allocCharData(m_charData);
}
bool merge() {
auto allocManger = shareMemoryManger();
if(!allocManger)
return false;
auto cacheCharData = allocManger->addCacheCharData(m_charData); //新数据加入
if(cacheCharData != m_charData) {
m_charData = cacheCharData;
return true;
} else {
return false;
}
}
private:
inline ShareDataMergeMangerSp shareMemoryManger() const {
if(m_shareDataMergeManger.expired())
return nullptr;
return m_shareDataMergeManger.lock();
}
public:
ShareDataSp m_charData;
ShareDocDataSp m_docData;
ShareDataMergeMangerWp m_shareDataMergeManger;
};
using LocalStyleSp = std::shared_ptr
class Style {
public:
std::string hyperLink;
int styleId;
ShareDataSp charData;
};
class DocStyle {
public:
ShareDocDataSp docData;
int align;
};
int main(int argc, char** argv)
{
auto shareDataManger = std::make_shared
auto shareCharData = std::make_shared
auto shareDocData = std::make_shared
BaseStyleSp localStyle = std::make_shared
float size = 1; //数据存在浮点精度,无法准确去重,暂时不优化
localStyle->setProperty(BaseStyle::ProperyID::PROP_FONT_SIZE, &size);
size = 2;
localStyle->setProperty(BaseStyle::ProperyID::PROP_FONT_SIZE, &size);
size = 0;
localStyle->setProperty(BaseStyle::ProperyID::PROP_FONT_SIZE, &size);
return 0;
}
perf-10万样式-同时修改1万个-5-6ms(堆内存频繁分配,合并,释放,尝试转栈)
#include
#include
int main(int argc, char** argv)
{
auto shareDataManger = std::make_shared
size_t count = 100000;
std::vector
vctStyles.reserve(count);
for (int i = 0; i < count; ++i) {
auto shareCharData = std::make_shared
auto shareDocData = std::make_shared
BaseStyleSp localStyle = std::make_shared
vctStyles.push_back(localStyle);
}
// 获取当前时间点
auto start = std::chrono::high_resolution_clock::now();
float size = 50000;
auto shareCharData = std::make_shared
auto shareDocData = std::make_shared
BaseStyleSp localStyle = std::make_shared
for (int i = 40000; i < 50000; ++i) {
size = i + 1;
vctStyles.at(i)->setProperty(BaseStyle::ProperyID::PROP_FONT_SIZE, &size);
}
// 获取代码执行后的时间点
auto end = std::chrono::high_resolution_clock::now();
// 计算代码执行的时间差
auto duration = std::chrono::duration_caststd::chrono::microseconds(end - start).count();
// 输出运行时间
std::cout << “代码执行时间: “ << duration << “ 微秒” << std::endl;
return 0;
}


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/139146932
支持所有常用编程语
https://capnproto.org/
GitHub - capnproto/capnproto: Cap’n Proto serialization/RPC system - core tools and C++ library
https://capnproto.org/capnproto-c++-win32-1.0.2.zip
常用命令:
capnp help
capnp compile -oc++ myschema.capnp
capnp decode myschema.capnp MyType < message.bin > message.txt
capnp encode myschema.capnp MyType < message.txt > message.bin
capnp eval myschema.capnp myConstant
myschema.capnp:
@0xa8712255ec118b18;
struct Person {
id @0 :UInt32;
name @1 :Text;
email @2 :Text;
phones @3 :List(PhoneNumber);
struct PhoneNumber {
number @0 :Text;
type @1 :Type;
enum Type {
mobile @0;
home @1;
work @2;
}
}
employment :union {
unemployed @4 :Void;
employer @5 :Text;
school @6 :Text;
selfEmployed @7 :Void;
# We assume that a person is only one of these.
}
}
struct AddressBook {
people @0 :List(Person);
}
示例代码:
#include “myschema.capnp.h”
#include <capnp/message.h>
#include <capnp/serialize-packed.h>
#include
void writeAddressBook(int fd) {
::capnp::MallocMessageBuilder message;
AddressBook::Builder addressBook = message.initRoot
::capnp::List
Person::Builder alice = people[0];
alice.setId(123);
alice.setName(“Alice”);
alice.setEmail(“alice@example.com“);
// Type shown for explanation purposes; normally you’d use auto.
::capnp::ListPerson::PhoneNumber::Builder alicePhones =
alice.initPhones(1);
alicePhones[0].setNumber(“555-1212”);
alicePhones[0].setType(Person::PhoneNumber::Type::MOBILE);
alice.getEmployment().setSchool(“MIT”);
Person::Builder bob = people[1];
bob.setId(456);
bob.setName(“Bob”);
bob.setEmail(“bob@example.com“);
auto bobPhones = bob.initPhones(2);
bobPhones[0].setNumber(“555-4567”);
bobPhones[0].setType(Person::PhoneNumber::Type::HOME);
bobPhones[1].setNumber(“555-7654”);
bobPhones[1].setType(Person::PhoneNumber::Type::WORK);
bob.getEmployment().setUnemployed();
writePackedMessageToFd(fd, message);
}
void printAddressBook(int fd) {
::capnp::PackedFdMessageReader message(fd);
AddressBook::Reader addressBook = message.getRoot
for (Person::Reader person : addressBook.getPeople()) {
std::cout << person.getName().cStr() << “: “
<< person.getEmail().cStr() << std::endl;
for (Person::PhoneNumber::Reader phone : person.getPhones()) {
const char* typeName = “UNKNOWN”;
switch (phone.getType()) {
case Person::PhoneNumber::Type::MOBILE: typeName = “mobile”; break;
case Person::PhoneNumber::Type::HOME: typeName = “home”; break;
case Person::PhoneNumber::Type::WORK: typeName = “work”; break;
}
std::cout << “ “ << typeName << “ phone: “
<< phone.getNumber().cStr() << std::endl;
}
Person::Employment::Reader employment = person.getEmployment();
switch (employment.which()) {
case Person::Employment::UNEMPLOYED:
std::cout << “ unemployed” << std::endl;
break;
case Person::Employment::EMPLOYER:
std::cout << “ employer: “
<< employment.getEmployer().cStr() << std::endl;
break;
case Person::Employment::SCHOOL:
std::cout << “ student at: “
<< employment.getSchool().cStr() << std::endl;
break;
case Person::Employment::SELF_EMPLOYED:
std::cout << “ self-employed” << std::endl;
break;
}
}
}
void test() {
auto file = fopen(“example.bin”, “wt+”);
if (!file)
return;
int fd = fileno(file); //如果是W+ 这里文件被清空的影响
writeAddressBook(fd);
fclose(file);
fflush(file);
file = fopen(“example.bin”, “rb+”);
fd = fileno(file);
printAddressBook(fd);
fclose(file);
}
运行输出:
Alice: alice@example.com
mobile phone: 555-1212
student at: MIT
Bob: bob@example.com
home phone: 555-4567
work phone: 555-7654
unemployed
其它类似参考:
GitHub - protocolbuffers/protobuf: Protocol Buffers - Google’s data interchange format
evanw (Evan Wallace) · GitHub


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/139127918
class A;
有序map:
std::unordered_map<std::weak_ptr, int, A, std::owner_less> text;
无序map:
class A
{
public:
A() : a(0) {}
A(int ss) : a(ss) {}
std::size_t hash() const { return std::hash
std::size_t operator()(const std::weak_ptr &p) const
{
if (p.expired())
return 0;
auto sharedPtr = p.lock();
if (!sharedPtr)
return 0;
return sharedPtr->hash();
}
bool operator==(const std::weak_ptr &other) const
{
std::shared_ptr otherPtr;
if (other.expired())
otherPtr = nullptr;
else
otherPtr = other.lock();
if (!otherPtr)
return false;
return hash() == otherPtr->hash();
}
class CharCmp
{
public:
bool operator()(const std::weak_ptr &p, const std::weak_ptr &other) const
{
std::shared_ptr selfPtr;
std::shared_ptr otherPtr;
if (p.expired())
selfPtr = nullptr;
else
selfPtr = p.lock();
if (other.expired())
otherPtr = nullptr;
else
otherPtr = other.lock();
if (selfPtr == otherPtr)
return true;
if (!selfPtr)
return false;
if (!otherPtr)
return false;
return selfPtr->hash() == otherPtr->hash();
}
};
int a = 0;
};
auto ptr = std::make_shared(2);
std::unordered_map<std::weak_ptr, int, A, A::CharCmp> text;
text.emplace(ptr, 0);
ptr->a = 3;
text.emplace(ptr, 0);
ptr = std::make_shared(2);
text.emplace(ptr, 0);


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/139013075


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/139010523
mkdir build && cd build
cmake -DCMAKE_CXX_COMPILER=”%VCINSTALLDIR%/bin/cl.exe” -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=”/mnt/include-what-you-use/build/bin/include-what-you-use” -G Ninja ..
export IWYU_BINARY=/mnt/include-what-you-use/build/bin/include-what-you-use
python3 /mnt/include-what-you-use/iwyu_tool.py -j 8 -p .> iwyu.out
python3 /mnt/include-what-you-use/fix_includes.py -b –comments –update_comments < iwyu.out
clang -pg -lstdc++ -o ./cmake/test ./cmake/cmake.cpp -lc_p
./cmake/test
gprof -b -qfunc1 fic_untilTool_test gmon.out>gmon.txt
gprof -b test gmon.out -Ffunc1 -efuncTest >gmon.txt
kprof -f ./test
gprof ./test | gprof2dot.py | xdot
-b 不显示描述
-A 显示函数源码
-pa 只打印a的flat profile,-Pa只屏蔽a
-qa 只打印a的call,-Qa只屏蔽a
sprof ./module.so Perf.profile -p >log.txt
time ./program
gcov ./summer-proj覆盖测试
gprof ./Perf | gprof2dot.py | dot -Tpng -o output.png
cd gprof2dot && cat ../bin/gmon.txt | python3 gprof2dot.py -n0 -e0 | dot -Tpdf -o output.pdf
编译开关-ftest-coverage -fprofile-arcs
改run.sh 换行类型
apt-get install ./libimagequant0_2.12.2-1.1_amd64.deb
apt-get install ./libimagequant-dev_2.12.2-1.1_amd64.deb
dpkg-deb -c quantum6.deb
泄露分析,编译链接-g
valgrind –tool=memcheck –leak-check=full –show-leak-kinds=all ./bin/Perf
valgrind –tool=callgrind ../bin/Perf
python gprof2dot.py -f callgrind -n10 -s callgrind.out.31113 | dot -Tpng -o valgrind.png
pprof安装
export CPUPROFILE_FREQUENCY=1
go install github.com/google/pprof@latest
pprof –text ./Perf test_capture.prof > profile.txt
pprof –callgrind ./Perf test_capture.prof > callgrind.res
pprof ./Perf test_capture.prof –web
pprof ./Perf test_capture.prof –pdf > prof.pdf
查看-pg是否生效
-lc_p
nm libobjectmodule.so | grep mcount
ldd ./Perf | grep libc
apt-get install libpopt-dev
apt-get install libiberty-dev
apt-get install libfdt-dev
#Recommended profilers¶
VerySleepy (Windows only)
HotSpot (Linux only)
Xcode Instruments (macOS only)


tag:
缺失模块。
1、请确保node版本大于6.2
2、在博客根目录(注意不是yilia根目录)执行以下命令:
npm i hexo-generator-json-content --save
3、在根目录_config.yml里添加配置:
jsonContent:
meta: false
pages: false
posts:
title: true
date: true
path: true
text: false
raw: false
content: false
slug: false
updated: false
comments: false
link: false
permalink: false
excerpt: false
categories: false
tags: true