你可以使用字节比较宏而不是
strcmp()
来实现非常快的字符串比较(标准 8 位
char
),如果你事先知道字符串长度。我对比了字节比较宏和 glibc 的
strcmp()
,宏版本明显优于
strcmp()
实现;它利用了 CPU 的
矢量处理器。
示例:
#define str3_cmp(x, y0, y1, y2, y3) x[0] == y0 && x[1] == y1 && x[2] == y2 && x[3] == y3
static inline bool str3_cmp_helper(const char *x, const char *y) {
return str3_cmp(x, *y, *(y + 1), *(y + 2), *(y + 3));
}
const char *i = "hola";
if (str3_cmp_helper(i, "hola")) {
} else {
}
然而,编写这样的宏是很繁琐的,因此我已经包含了一个PHP脚本来生成宏。该脚本需要两个参数,(1)要比较的字符串长度(此参数为
可变参数,因此您可以编写尽可能多的宏),以及(2)输出文件名。
<?php
function generate_macro($num) : string {
$returner = "#define str".$num."cmp_macro(ptr, ";
for($x = 0; $x < $num; $x++){
$returner .= "c".$x;
if($x != $num-1){ $returner .= ", "; }
}
$returner .= ") ";
for($x = 0; $x < $num; $x++){
$returner .= "*(ptr+".$x.") == c".$x;
if($x != $num-1){ $returner .= " && "; }
}
return $returner;
}
function generate_static_inline_fn(&$generated_macro, $num) : string {
$generated_macro .= "static inline bool str".$num."cmp(const char* ptr, const char* cmp)".
"{\n\t\treturn str".$num."cmp_macro(ptr, ";
for($x = 0; $x < $num; $x++){
$generated_macro .= " *(cmp+".$x.")";
if($x != $num-1){ $generated_macro .= ", "; }
}
$generated_macro .= ");\n}\n";
return $generated_macro;
}
function handle_generation($argc, $argv) : void {
$out_filename = $argv[$argc-1];
$gen_macro = "";
for($x = 0; $x < $argc-2; $x++){
$macro = generate_macro($argv[$x+1])."\n";
$gen_macro .= generate_static_inline_fn($macro, $argv[$x+1]);
}
file_put_contents($out_filename, $gen_macro);
}
handle_generation($argc, $argv);
?>
脚本示例:$ ./gen_faststrcmp.php 3 5 fast_strcmp.h
。
这将生成fast_strcmp.h
,其中包含用于比较长度为3和5的字符串的宏:
#define str3cmp_macro(ptr, c0, c1, c2) *(ptr+0) == c0 && *(ptr+1) == c1 && *(ptr+2) == c2
static inline bool str3cmp(const char* ptr, const char* cmp){
return str3cmp_macro(ptr, *(cmp+0), *(cmp+1), *(cmp+2));
}
#define str5cmp_macro(ptr, c0, c1, c2, c3, c4) *(ptr+0) == c0 && *(ptr+1) == c1 && *(ptr+2) == c2 && *(ptr+3) == c3 && *(ptr+4) == c4
static inline bool str5cmp(const char* ptr, const char* cmp){
return str5cmp_macro(ptr, *(cmp+0), *(cmp+1), *(cmp+2), *(cmp+3), *(cmp+4));
}
您可以像这样使用宏:
const char* compare_me = "Hello";
if(str5cmp(compare_me, "Hello")) { }