switch case 与map哪个效率高?

68 篇文章 3 订阅
21 篇文章 1 订阅

从直觉来看,应该是map高,因为通过索引来对比应该比反复的判断并jmp来的快,但事实上违反直觉的是,当少量的键值对查找时候,发现switch快了一倍多!!!

// justTestit.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <map>
#include <unordered_map>
#include <regex>
#include "MyTimer.h"

using namespace std;
using namespace oneapm;

inline std::string file_extension(const std::string &path) {
	std::smatch m;
	static auto re = std::regex("\\.([a-zA-Z0-9]+)$");
	if (std::regex_search(path, m, re)) { return m[1].str(); }
	return std::string();
}

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);
}

namespace udl {

	inline constexpr unsigned int operator"" _t(const char *s, size_t l) {
		return str2tag_core(s, l, 0);
	}

} // namespace udl

inline const char *
find_content_type(const std::string &ext) {

	using udl::operator""_t;

	switch (str2tag(ext)) {
	default: return nullptr;
	case "css"_t: return "text/css";
	case "csv"_t: return "text/csv";
	case "txt"_t: return "text/plain";
	case "vtt"_t: return "text/vtt";
	case "htm"_t:
	case "html"_t: return "text/html";

	case "apng"_t: return "image/apng";
	case "avif"_t: return "image/avif";
	case "bmp"_t: return "image/bmp";
	case "gif"_t: return "image/gif";
	case "png"_t: return "image/png";
	case "svg"_t: return "image/svg+xml";
	case "webp"_t: return "image/webp";
	case "ico"_t: return "image/x-icon";
	case "tif"_t: return "image/tiff";
	case "tiff"_t: return "image/tiff";
	case "jpg"_t:
	case "jpeg"_t: return "image/jpeg";

	case "mp4"_t: return "video/mp4";
	case "mpeg"_t: return "video/mpeg";
	case "webm"_t: return "video/webm";

	case "mp3"_t: return "audio/mp3";
	case "mpga"_t: return "audio/mpeg";
	case "weba"_t: return "audio/webm";
	case "wav"_t: return "audio/wave";

	case "otf"_t: return "font/otf";
	case "ttf"_t: return "font/ttf";
	case "woff"_t: return "font/woff";
	case "woff2"_t: return "font/woff2";

	case "7z"_t: return "application/x-7z-compressed";
	case "atom"_t: return "application/atom+xml";
	case "pdf"_t: return "application/pdf";
	case "js"_t:
	case "mjs"_t: return "application/javascript";
	case "json"_t: return "application/json";
	case "rss"_t: return "application/rss+xml";
	case "tar"_t: return "application/x-tar";
	case "xht"_t:
	case "xhtml"_t: return "application/xhtml+xml";
	case "xslt"_t: return "application/xslt+xml";
	case "xml"_t: return "application/xml";
	case "gz"_t: return "application/gzip";
	case "zip"_t: return "application/zip";
	case "wasm"_t: return "application/wasm";
	}
}


inline const char * find_content_type1(const std::string ext)
{
	static std::unordered_map<std::string, std::string> tagMap =
	{
	{"css", "text/css"},
	{"csv", "text/csv"},
	{"htm", "text/html"},
	{"html", "text/html"},
	{"js", "text/javascript"},
	{"mjs", "text/javascript"},
	{"txt", "text/plain"},
	{"vtt", "text/vtt"},

	{"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"},
	{"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"}
	};

	auto it = tagMap.find(ext);
	if (it == tagMap.end())
	{
		return nullptr;
	}
	else
	{
		return it->second.c_str();
	}
}

inline const char * find_content_type2(const std::string ext)
{
	using udl::operator""_t;

	static std::unordered_map<unsigned int, std::string> tagMap =
	{
	{"css"_t, "text/css"},
	{"csv"_t, "text/csv"},
	{"htm"_t, "text/html"},
	{"html"_t, "text/html"},
	{"js"_t, "text/javascript"},
	{"mjs"_t, "text/javascript"},
	{"txt"_t, "text/plain"},
	{"vtt"_t, "text/vtt"},

	{"apng"_t, "image/apng"},
	{"avif"_t, "image/avif"},
	{"bmp"_t, "image/bmp"},
	{"gif"_t, "image/gif"},
	{"png"_t, "image/png"},
	{"svg"_t, "image/svg+xml"},
	{"webp"_t, "image/webp"},
	{"ico"_t, "image/x-icon"},
	{"tif"_t, "image/tiff"},
	{"tiff"_t, "image/tiff"},
	{"jpg"_t, "image/jpeg"},
	{"jpeg"_t, "image/jpeg"},

	{"mp4"_t, "video/mp4"},
	{"mpeg"_t, "video/mpeg"},
	{"webm"_t, "video/webm"},

	{"mp3"_t, "audio/mp3"},
	{"mpga"_t, "audio/mpeg"},
	{"weba"_t, "audio/webm"},
	{"wav"_t, "audio/wave"},

	{"otf"_t, "font/otf"},
	{"ttf"_t, "font/ttf"},
	{"woff"_t, "font/woff"},
	{"woff2"_t, "font/woff2"},

	{"7z"_t, "application/x-7z-compressed"},
	{"atom"_t, "application/atom+xml"},
	{"pdf"_t, "application/pdf"},
	{"json"_t, "application/json"},
	{"rss"_t, "application/rss+xml"},
	{"tar"_t, "application/x-tar"},
	{"xht"_t, "application/xhtml+xml"},
	{"xhtml"_t, "application/xhtml+xml"},
	{"xslt"_t, "application/xslt+xml"},
	{"xml"_t, "application/xml"},
	{"gz"_t, "application/gzip"},
	{"zip"_t, "application/zip"},
	{"wasm"_t, "application/wasm"}
	};
	unsigned int code = str2tag(ext);
	auto it = tagMap.find(code);
	if (it == tagMap.end())
	{
		return nullptr;
	}
	else
	{
		return it->second.c_str();
	}
}

int main()
{
	static std::map<std::string, std::string> tagMap1 =
	{
	{"css", "text/css"},
	{"csv", "text/csv"},
	{"htm", "text/html"},
	{"html", "text/html"},
	{"js", "text/javascript"},
	{"mjs", "text/javascript"},
	{"txt", "text/plain"},
	{"vtt", "text/vtt"},

	{"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"},
	{"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"}
	};

	Timer timer;
	timer.start();
	for (int i=0; i<1000; i++)
		for (auto it : tagMap1)
		{
			const char * data = find_content_type(it.first);
		}
	double delta = timer.stop_delta_ms();
	std::cout << delta << endl;

	timer.start();
	for (int i = 0; i < 1000; i++)
		for (auto it : tagMap1)
		{
			const char * data = find_content_type1(it.first);
		}
	delta = timer.stop_delta_ms(); 
	std::cout << delta << endl;

	timer.start();
	for (int i = 0; i < 1000; i++)
		for (auto it : tagMap1)
		{
			const char * data = find_content_type2(it.first);
		}
	delta = timer.stop_delta_ms();

	std::cout << delta << endl;
}

0.7367   // swith case
2.3099   // string map
2.1375   //  int map

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值