UUID 已经使用了很多年并且存在多种生成方法。
我更喜欢 PECL 扩展而不是 ramsey/uuid 包,因为它更的简单明了。数周前,我们有了将 PECL 扩展移植到纯 PHP 的想法,与 Nicolas Grekas 一起,我们将其发布为 Symfony Polyfill。然后,我们想写博客介绍 FFI 这一 PHP 7.4 的新功能。因此,与 Baptiste Leduc 一起,我们将 libuuid 库与 PHP 进行了绑定。
因此,现在至少有四种方法可以用 PHP 生成 UUID,让我们进行对比:
PECL 扩展的 PHP 实现包 polyfill ;
一个建立在多个版本生成器和 UUID 组件之上的抽象层 ramsey/uuid;
用于 PHP 7.4 以上版本的 FFI 绑定;
我创建了一组 基准测试可以对这些实现进行比较。
UUID V1 版本 (基于时间)
+----------------------+---------+-------+
| 主题 | 平均时间 | 插值 |
+----------------------+---------+-------+
| benchPecl | 0.637μs | 1.00x |
| benchSymfonyPolyfill | 1.736μs | 2.72x |
| benchJoliCodeFFI | 1.349μs | 2.12x |
| benchRamsey | 4.295μs | 6.74x |
+----------------------+---------+-------+
UUID V4 版本 (随机数)
+----------------------+---------+-------+
| 主题 | 平均时间 | 插值 |
+----------------------+---------+-------+
| benchPecl | 4.546μs | 2.87x |
| benchSymfonyPolyfill | 1.583μs | 1.00x |
| benchJoliCodeFFI | 5.416μs | 3.42x |
| benchRamsey | 2.103μs | 1.33x |
+----------------------+---------+-------+
这些版本有什么不同?
V1
V1 是基于时间的。它没有太多随机数据,但是每个 UUID 必须是唯一的,因此需要一个内部计数器。
PECL 是这里最快的,因为它使用内核的一些特性来获得增量数据。
FFI 绑定比较慢,因为在底层库中,FFI 对于速度非常快的东西会有很大的开销。这种开销来自于 PHP 和底层库之间的转换类型。
Polyfill 的速度较慢,因为它必须手动处理计数器。
Rasmey 实现最慢,因为它处理计数器的方式可以改进。
V4
V4 充满了随机数据。这意味着 CPU 生成一个 V4 比生成一个 V1 更加昂贵。
由于 PHP 的原因 Polyfill 是最快的。PHP 使用了 sys_getrandom() ,一种更快的方式来获取随机数据。
由于相同的原因,Rasmey 实现也非常快。
PECL 的运行速度要慢得多,因为底层库 (libuuid) 每次从 PHP 的代码中调用 uuid_create() 时都会在 /dev/urandom 上打开一个新的文件描述符。
FFI 绑定是最慢的,因为它依赖于相同的 libuuid 库,并且增加了 FFI 开销。
结论
现在您已经了解了有关 uuid 的所有知识,因此… 只需做出 正确的选择. ;)
请记住,FFI 绑定仅适用于 PHP 7.4+,因此(目前)在很多项目中可能无法使用。
ramsey / uuid 是一个利用许多 UUID 生成器的 UUID 组件(它可以在内部使用 PECL )。在 ramsey / uuid 实现中使用 polyfill 可能会很有意思。
由于 polyfill 与 PECL 扩展是一样的,所以最后的选择是关于 API 的:
简单的:PECL(如果您无法安装扩展程序,则使用 polyfill )。
更加丰富的功能:ramsey / uuid 组件。
成熟的:FFI 绑定。
现在,您了解了所有使用 PHP 生成 UUID 的方法,只需要使用合适的方法即可。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。