我需要编写一个函数来测试,如果给定的字符串在某种意义上是“空白”,它只包含空格字符。空白字符如下:
'\u0009',
'\u000A',
'\u000B',
'\u000C',
'\u000D',
' ',
'\u0085',
'\u00A0',
'\u1680',
'\u180E',
'\u2000',
'\u2001',
'\u2002',
'\u2003',
'\u2004',
'\u2005',
'\u2006',
'\u2007',
'\u2008',
'\u2009',
'\u200A',
'\u2028',
'\u2029',
'\u202F',
'\u205F',
'\u3000'
该函数将被调用很多次,因此它必须非常非常高效。但不应占用太多内存(例如将每个字符映射到数组中的真/假)。到目前为止我尝试过的事情:
- 正则表达式 - 性能不太好
- 修剪并检查长度是否为 0 - 性能不佳,还使用额外的内存来保存修剪后的字符串
- 根据包含空白字符 (
if (!whitespaceCharactersMap[str[index]]) ...
) 的哈希集检查每个字符串字符 - 效果很好 我当前的解决方案使用硬编码比较:
function(str) { var length = str.length; if (!length) { return true; } for (var index = 0; index < length; index++) { var c = str[index]; if (c === ' ') { // skip } else if (c > '\u000D' && c < '\u0085') { return false; } else if (c < '\u00A0') { if (c < '\u0009') { return false; } else if (c > '\u0085') { return false; } } else if (c > '\u00A0') { if (c < '\u2028') { if (c < '\u180E') { if (c < '\u1680') { return false; } else if(c > '\u1680') { return false; } } else if (c > '\u180E') { if (c < '\u2000') { return false; } else if (c > '\u200A') { return false; } } } else if (c > '\u2029') { if (c < '\u205F') { if (c < '\u202F') { return false; } else if (c > '\u202F') { return false; } } else if (c > '\u205F') { if (c < '\u3000') { return false; } else if (c > '\u3000') { return false; } } } } } return true; }
这似乎比哈希集(在 Chrome 上测试)快 50-100%。
有人看到或知道更多选择吗?
更新 1
我将在这里回答一些评论:
- 这不仅仅是检查用户输入是否为空。我必须解析必须单独处理空格的某些数据格式。
- 值得优化。我之前已经分析过代码。检查空白字符串似乎是一个问题。而且,正如我们所看到的,方法之间的性能差异可能高达 10 倍,这绝对值得付出努力。
- 一般来说,我发现这个“哈希集 vs. 正则表达式 vs. 切换 vs. 分支”挑战很有教育意义。
- 对于浏览器和 node.js,我需要相同的功能。
现在这是我对性能测试的看法:
http://jsperf.com/hash-with-comparisons/6
如果你们进行几次这些测试,我将不胜感激。
初步结论:
- branchlessTest (
a^9*a^10*a^11...
) 在 Chrome 和 Firefox 中非常快,但在 Safari 中则不然。从性能角度来看,这可能是 Node.js 的最佳选择。 - switchTest 在 Chrom 和 Firefox 上也相当快,但令人惊讶的是在 Safari 和 Opera 上最慢
- 带有 re.test(str) 的正则表达式在任何地方都表现良好,甚至在 Opera 中也是最快的。
- 散列和分支几乎在所有地方都显示出几乎相同的差结果。对比也差不多,往往性能最差(这可能是实现的原因,check for
' '
应该是第一个)。
总而言之,就我而言,我将选择以下正则表达式版本:
var re = /[^\s]/;
return !re.test(str);
原因:
- 无分支版本在 Chrome 和 Firefox 中很酷,但不太便携
- 在 Safari 中切换太慢
- 正则表达式似乎在任何地方都表现良好,它们的代码也非常紧凑