概述
需求:
1)执行期间将文件名的扩展映射为具体的内容信息返回;
2)可以理解为键值对查找;
解决方法:
1)普通的解决方案:使用std::map<string, string>管理并查找;
2)constexpr解决方案:直接写为switch case 方式;
先内联2个函数,作为字符串转int的哈希:
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);
}
方式一:
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
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;
}
}
测试代码:
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 关键字优化 字符串映射与查找所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复