我是靠谱客的博主 土豪蓝天,这篇文章主要介绍constexpr 关键字优化 字符串映射与查找,现在分享给大家,希望可以做个参考。

需求:

1)执行期间将文件名的扩展映射为具体的内容信息返回;

2)可以理解为键值对查找;

解决方法:

1)普通的解决方案:使用std::map<string, string>管理并查找;

2)constexpr解决方案:直接写为switch    case 方式;

先内联2个函数,作为字符串转int的哈希:

复制代码
1
2
3
4
5
6
7
8
9
10
inline constexpr unsigned int str2tag_core(const char *s, size_t l, unsigned int h) { return (l == 0) ? h : str2tag_core(s + 1, l - 1, (h * 33) ^ static_cast<unsigned char>(*s)); } inline unsigned int str2tag(const std::string &s) { return str2tag_core(s.data(), s.size(), 0); }

方式一:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
inline const char * find_content_type1(const string &ext) { auto it = tagStrMap.find(ext); if (it != tagStrMap.end()) { return it->second.c_str(); } return nullptr; } inline const char * find_content_type2(const string &ext) { unsigned int code; static std::map<unsigned int, std::string> tagMap; if (tagMap.size() == 0) { for (auto & it : tagStrMap) { code = str2tag(it.first); //printf("set code %u : %s n", code, it.second.c_str()); /*auto it2 = tagMap.find(code); if (it2 != tagMap.end()) { printf("same----n"); }*/ tagMap.insert(std::make_pair(code, it.second)); } } code = str2tag(ext); auto item = tagMap.find(code); if (item != tagMap.end()) { return item->second.c_str(); } return nullptr; }

方法二:编译器常量表达式执行swich case

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
inline constexpr unsigned int CpmCode(const char *s, size_t l) { return str2tag_core(s, l, 0); } const char * findConent1(const char* ext) { unsigned int code = str2tag(ext); switch (code) { case CpmCode("css", 3): return "text/css"; case CpmCode("csv", 3): return "text/csv"; case CpmCode("txt", 3): return "text/plain"; case CpmCode("vtt", 3): return "text/vtt"; case CpmCode("htm", 3): case CpmCode("html", 4): return "text/html"; case CpmCode("apng", 4): return "image/apng"; case CpmCode("avif", 4): return "image/avif"; case CpmCode("bmp", 3): return "image/bmp"; case CpmCode("gif", 3): return "image/gif"; case CpmCode("png", 3): return "image/png"; case CpmCode("svg", 3): return "image/svg+xml"; case CpmCode("webp", 4): return "image/webp"; case CpmCode("ico", 3): return "image/x-icon"; case CpmCode("tif", 3): return "image/tiff"; case CpmCode("tiff", 4): return "image/tiff"; case CpmCode("jpg", 3): case CpmCode("jpeg", 4): return "image/jpeg"; case CpmCode("mp4", 3): return "video/mp4"; case CpmCode("mpeg", 4): return "video/mpeg"; case CpmCode("webm", 4): return "video/webm"; case CpmCode("mp3", 3): return "audio/mp3"; case CpmCode("mpga", 4): return "audio/mpeg"; case CpmCode("weba", 4): return "audio/webm"; case CpmCode("wav", 3): return "audio/wave"; case CpmCode("otf", 3): return "font/otf"; case CpmCode("ttf", 3): return "font/ttf"; case CpmCode("woff", 4): return "font/woff"; case CpmCode("woff2", 5): return "font/woff2"; case CpmCode("7z", 2): return "application/x-7z-compressed"; case CpmCode("atom", 3): return "application/atom+xml"; case CpmCode("pdf", 3): return "application/pdf"; case CpmCode("js", 2): case CpmCode("mjs", 3): return "application/javascript"; case CpmCode("json", 4): return "application/json"; case CpmCode("rss", 3): return "application/rss+xml"; case CpmCode("tar", 3): return "application/x-tar"; case CpmCode("xht", 3): case CpmCode("xhtml", 5): return "application/xhtml+xml"; case CpmCode("xslt", 4): return "application/xslt+xml"; case CpmCode("xml", 3): return "application/xml"; case CpmCode("gz", 2): return "application/gzip"; case CpmCode("zip", 3): return "application/zip"; case CpmCode("wasm", 4): return "application/wasm"; default: return nullptr; } }

测试代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
double test1(const string & ext) { Timer timer; const char * textCss = find_content_type1("css"); timer.start(); for (int i=0; i<20; i++) { const char * textZip = find_content_type1(ext.c_str()); } double delta = timer.stop_delta_us(); return delta; } double test2(const string & ext) { Timer timer; const char * textCss = find_content_type2("css"); timer.start(); for (int i = 0; i < 20; i++) { const char * textZip = find_content_type2(ext.c_str()); } double delta = timer.stop_delta_us(); return delta; } double test3(const string & ext) { Timer timer; timer.start(); for (int i = 0; i < 20; i++) { const char * textZip = findConent1(ext.c_str()); } double delta = timer.stop_delta_us(); return delta; } int main(void) { static std::map<std::string, std::string> tagStrMap1 { {"css", "text/css"}, {"csv", "text/csv"}, {"txt", "text/plain"}, {"vtt", "text/vtt"}, {"htm", "text/html"}, {"html", "text/html"}, {"apng", "image/apng"}, {"avif", "image/avif"}, {"bmp", "image/bmp"}, {"gif", "image/gif"}, {"png", "image/png"}, {"svg", "image/svg+xml"}, {"webp", "image/webp"}, {"ico", "image/x-icon"}, {"tif", "image/tiff"}, {"tiff", "image/tiff"}, {"jpg", "image/jpeg"}, {"jpeg", "image/jpeg"}, {"mp4", "video/mp4"}, {"mpeg", "video/mpeg"}, {"webm", "video/webm"}, {"mp3", "audio/mp3"}, {"mpga", "audio/mpeg"}, {"weba", "audio/webm"}, {"wav", "audio/wave"}, {"otf", "font/otf"}, {"ttf", "font/ttf"}, {"woff", "font/woff"}, {"woff2", "font/woff2"}, {"7z", "application/x-7z-compressed"}, {"atom", "application/atom+xml"}, {"pdf", "application/pdf"}, {"js", "application/javascript"}, {"mjs", "application/javascript"}, {"json", "application/json"}, {"rss", "application/rss+xml"}, {"tar", "application/x-tar"}, {"xht", "application/xhtml+xml"}, {"xhtml", "application/xhtml+xml"}, {"xslt", "application/xslt+xml"}, {"xml", "application/xml"}, {"gz", "application/gzip"}, {"zip", "application/zip"}, {"wasm", "application/wasm"} }; for (auto it : tagStrMap1) { string ext = it.first; double t1 = test1(ext); double t2 = test2(ext); double t3 = test3(ext); printf("%f, %f, %fn", t1, t2, t3); }

结果是:使用字符串直接放到map里还是最快的!!!

最后

以上就是土豪蓝天最近收集整理的关于constexpr 关键字优化 字符串映射与查找的全部内容,更多相关constexpr内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部