心心念唸的最佳化完成了,雖然不是很完美
來源:高效能架構探索
你好,我是雨樂!
核心模組有個功能點,一直以來想著將其最佳化掉(雖然線上上穩定執行了這麼多年),要麼沒時間,要麼懶的搞,一拖再拖。期間也想了各種方案,無奈不是很完美,恰好吳老師進群了,隨向有著20多年經驗的吳老師進行了請教,也跟A總,E總等進行了討論,慢慢的也有了最佳化思路,於是用了大概一天的時間,基於這幾個大佬的方案,進行了最佳化。
需求
專案中有這樣一個需求,根據一個類別名以及其對應的型別,建立對應的資料結構。需求很簡單吧。。。
最佳化前的版本,先建立一個配置,然後程式啟動的時候,載入跟配置,然後根據配置內容進行相應的操作。
配置如下:
config.json
{
"phone_brand":"string",
"gender":"int"
}
解析如下:
// parse config.json
if (pare("config.json").failed()) {
return;
}
for (const auto & item : parse.elements()) {
auto name = item.first();
auto type = item.second();
if (type == "string") {
mp[name] = std::make_shared<Session<std::string>>(name);
} else if (type == "int") {
mp[name] = std::make_shared<Session<int>>(name);
}
}
其實,說實話,如果沒有潔癖的話,這段程式碼也不是不可行?。也線上穩定執行了幾年,不過,多少感覺這種方式很傻瓜,就像要求寫一個演算法,而自己實現了一個冒泡一樣,雖然功能滿足,但方案並不優雅。
方案一: typelist
既然需求是根據字串型別來建立對應的資料型別,那麼不妨把各種資料型別結合起來,而支援多種資料型別的,對於這種多型別的,第一時間想到了std::variant和std::tuple,不過因為std::variant使用上的限制以及實現本功能的話需要增加很多判斷程式碼,所以最終選擇了std::tuple來實現:
using types = std::tuple<int, double, std::string, int64_t>;
template<std::size_t N>
using StrType = typename std::tuple_element<N, types>::type;
constexpr bool strings_equal(const char* a, const char* b) {
return *a == *b && (*a == '\0' || strings_equal(a + 1, b + 1));
}
constexpr std::size_t getIdx(const char* name)
{
return strings_equal(name, "int") ? 0:
strings_equal(name, "double") ? 1:
strings_equal(name, "std::string") ? 2:
strings_equal(name, "int64_t") ? 3 : 4;
}
int main() {
if (pare("config.json").failed()) {
return;
}
for (const auto & item : parse.elements()) {
auto name = item.first();
auto type = item.second();
mp[name] = std::make_shared<Session<StrType<getIdx(type)>>>(name);
}
}
在上述中,依然採取配置檔案的方式,建立了一個支援int、string等型別的std::tuple,並透過getIdx和strings_equal來獲取該型別在tuple中的index,進而建立相應的型別。
其實,如果把該方案跟現有實現(第一個)相比較的話,並沒有變得多優雅,反而多了很多程式碼。。。
方案二: reflection
其實,這種需求從概念上講,應該是reflection,中文稱為反射,眾所周知C++標準委員會那幫人不食人間煙火,也一直沒有將反射納入標準。這塊也在群裡進行了討論,也聊了java中反射的實現機制和其弊端。其間,吳老師也發表了相關意見,原來對於反射這塊,於13年就專門成立了反射研究組,只是一直沒達到能進標準的共識。具體可以參考靜態反射。
如果對需求進行重構的話,我的需求也比較簡單,就是一個struct,裡面有各種變數,需要實現一個功能,就是獲取struct中的變數list以及對應的變數內容:
struct Config {
int a;
std::string b;
};
void fun() {
Config cfg;
std::vector<Filed> fileds = GetFileds(cfg);
for (const auto & item : fileds) {
auto name = item.name();
auto c = std::make_shared<item::type>();
// do other sth
}
}
於是在gayhub上也調研了實現,沒有一個特別滿意的方法,因為專案中大量用到了pb,所以藉助pb的反射功能來進行實現:
message Config {
int32 a;
string b;
}
Config category;
const google::protobuf::Descriptor* desc = category.GetDescriptor();
std::vector<const google::protobuf::FieldDescriptor *> vfd;
for (int i = 0; i < desc->field_count(); ++i) {
const google::protobuf::FieldDescriptor* fd = desc->field(i);
const auto &category_name = fd->name();
switch(fd->cpp_type()) {
case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
auto name = item.name();
auto c = std::make_shared<std::string>();
break;
}
case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
auto name = item.name();
auto c = std::make_shared<uint32_t>();
break;
}
default:
break;
}
}
上面這塊藉助於pb也基本滿足了需求,唯一不足的是需要有這個switch case,需要將pb的type轉換成cpp支援的type,不過不過怎麼說,也比現線上上的方式要優雅的多。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027824/viewspace-2951462/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Python雖然很火,為啥找工作這麼難?Python
- 大家心心念唸的RocketMQ5.x入門手冊來嘍MQ
- 23 種設計模式的通俗解釋,雖然有點汙,但是很正點設計模式
- 我們應該如何看待馬斯克心心念唸的“超迴圈”技術馬斯克
- 雖然《劍/盾》寶可夢確實很醜,但設計上還是很有趣的
- 你們心心念唸的《CD2:陷阱大師》EA版今天終於上線了
- 本文雖然不是laravel相關的技術部落格,但是我還是放在了laravel下。與君共勉Laravel
- 個性化的桌面,雖然這是臺工作機。
- 雖然Kubernetes可能是基礎設施的未來,但它不是開發者平臺 | devops.loldev
- .Net Core下使用RabbitMQ比較完備的兩種方案(雖然程式碼有點慘淡,不過我會完善)MQ
- 雖然包含string標頭檔案但未用std::
- .NET自定義認證雖然簡單,但好用
- noip模擬29[簡單的板子題](雖然我不會)
- 求迴文子序列個數(雖然字串,但是DP)字串
- 我活成了自己曾經很鄙視的樣子
- 7.5 - 貪心篇完結
- 雖然讓人不爽 但Epic確實正在撼動Steam的統治
- 學習3D建模很難嗎,是不是很辛苦?3D
- 算是秋招上岸的一些想法吧。(雖然現在都已經春招了。。
- 這5款軟體雖然知名度不高,但不代表不好用
- 心態:晉升的為什麼不是你
- OneThink是不是很難做到複雜模型?模型
- 瀏覽器說:雖然都叫event loop,但是我和node不一樣瀏覽器OOP
- 框架雖然讓你節省大量樣板程式碼,但是需要花費時間學習,編寫程式碼並不是快速交付的瓶頸 -Ouarzy的部落格框架
- 衝一下阿里,感覺不是很難阿里
- 扎心實戰案例:麻(shi)雀(zhan)雖小,五臟俱全
- 科技愛好者週刊(第 302 期):創業雖然好,不敢推薦了創業
- 而在2021年,Keep前三季度MAU雖然呈現強勢反彈
- 2020年2月資料庫流行度排行:冬日雖然寒冷,春光必定燦爛資料庫
- 雖然這款遊戲披著塑料皮,但我還是想稱其“小忍龍”遊戲
- 什麼。你還沒有搞懂Spring事務增強器 ,一篇文章讓你徹底搞懂Spring事務,雖然很長但是乾貨滿滿Spring
- 雖然是我遇到的一個棘手的生產問題,但是我寫出來之後,就是你的了。
- 揭祕3個自媒體運營技巧,你是不是也很心動別人做自媒體月入過萬?
- 爐石設計漫談:不完美的達拉然大劫案
- 《心流》——每天十分鐘,解讀完本書
- 文章編輯/釋出選擇分類不是很明顯
- 當然不是草臺班子 雲譯網 原型設計+概要設計原型
- 雖然這塊主機板價格有點小貴,但用過之後,感覺還是可以接受的