在开发中,我们经常需要生成唯一标识符,通常称为 GUID(全局唯一标识符)或 UUID(通用唯一标识符)。这些标识符在许多场景中都非常有用,例如数据库中的唯一记录标识、系统用户会话跟踪等。那么,如何高效地创建一个符合 RFC4122 标准的 GUID/UUID 呢?
今天,我将带大家探索几种生成 UUID 的方法,从中挑选出最优化的方案。一起来看看吧!
最初的实现
我们从一种常见的实现方法开始,这段代码来自 broofa 的回答:
function broofa() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
console.log(broofa());
这段代码通过字符串替换和正则表达式生成 UUID。虽然这样简单易读,并且符合 RFC4122 标准,但在性能上可能存在瓶颈。
性能优化之旅
优化1:移除正则表达式
正则表达式和函数调用是性能的主要瓶颈。我们首先移除正则表达式,改用简单的循环:
function e1() {
var u = '', i = 0;
while (i++ < 36) {
var c = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'[i-1], r = Math.random()*16|0, v = c == 'x' ? r : (r & 0x3 | 0x8);
u += (c == '-' || c == '4') ? c : v.toString(16);
}
return u;
}
console.log(e1());
这种方式实现的性能几乎提升了3倍!
优化2:减少 Math.random() 调用
我们可以减少 Math.random() 的调用,利用一个随机缓冲区来生成多个随机位:
function e2() {
var u = '', m = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'