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_ptrBaseStyle;class ShareData {public:ShareData(float fontSize): m_fontSize(fontSize){}size_t hash() const { return std::hashfloat()(m_fontSize);}public:float m_fontSize;};using ShareDataSp std::shared_ptrShareData;using ShareDataWp std::weak_ptrShareData;class ShareDocData {public:float paragraphIndent;};using ShareDocDataSp std::shared_ptrShareDocData;using ShareDocDataWp std::weak_ptrShareDocData;class ShareDataLRU {public:ShareDataLRU(): m_hitCount(0) {}int m_hitCount;};#include cassert#include unordered_mapclass 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_sharedShareData(*charData);}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);elseiter;}}public:std::unordered_mapShareDataSp, ShareDataLRU, CharHash, CharCmp manger;};using ShareDataMergeMangerSp std::shared_ptrShareDataMergeManger;using ShareDataMergeMangerWp std::weak_ptrShareDataMergeManger;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_ptrLocalStyle;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_sharedShareDataMergeManger();auto shareCharData std::make_sharedShareData(0);auto shareDocData std::make_sharedShareDocData();BaseStyleSp localStyle std::make_sharedLocalStyle(shareCharData, shareDocData, shareDataManger);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 iostream#include chronoint main(int argc, char** argv){auto shareDataManger std::make_sharedShareDataMergeManger();size_t count 100000;std::vectorBaseStyleSp vctStyles;vctStyles.reserve(count);for (int i 0; i count; i) {auto shareCharData std::make_sharedShareCharData(i);auto shareDocData std::make_sharedShareDocData();BaseStyleSp localStyle std::make_sharedLocalStyle(shareCharData, shareDocData, shareDataManger);vctStyles.push_back(localStyle);}// 获取当前时间点auto start std::chrono::high_resolution_clock::now();float size 50000;auto shareCharData std::make_sharedShareCharData(size);auto shareDocData std::make_sharedShareDocData();BaseStyleSp localStyle std::make_sharedLocalStyle(shareCharData, shareDocData, shareDataManger);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;}创作不易小小的支持一下吧
阅读完成 · 觉得有帮助?