返回首页

类型安全的 PHP 数组:+4x 速度

本文分析了 sbwerewolf/language-specific 库的优化:4x 加速,与 wplake/typed 的比较。提供了基准测试、链式 API 代码示例,以及不可变性等新功能。

PHP:类型安全的数组快 4 倍
Advertisement 728x90

PHP 类型安全数组:不牺牲可读性,性能提升 4 倍

sbwerewolf/language-specific 库 10.4.5 版本相较 8.4.1 版本实现 4 倍性能跃升;与当前竞品 wplake/typed(1.2.2)的性能差距已收窄至仅 2 倍。前者依赖字符串路径定位数据,后者则采用方法链式调用处理嵌套结构。

使用 wplake/typed 的示例:

use WPLake\Typed;

$response = file_get_contents(
    'https://geocode-maps.yandex.ru/1.x/?apikey=d3893dc1-c136-4084-b9c-4db26b00463e&geocode=Mohammed+Bin+Rashid+Boulevard+1&lang=en_US&format=json'
);

$object = json_decode(json: $response, associative: true, flags: JSON_THROW_ON_ERROR);

$path = 'response.GeoObjectCollection.featureMember.0.GeoObject.metaDataProperty.GeocoderMetaData.Address.formatted';

// 带默认值的安全取值
$val = Typed::string($object, $path, '地址未找到');
var_dump($val);
/*
string(77)
"1, 穆罕默德·本·拉希德大道, 迪拜市中心, 迪拜, 阿拉伯联合酋长国"
*/

$isReal = Typed::stringOrNull($object, $path) !== null;
var_dump($isReal);
/* bool(true) */

sbwerewolf/language-specific 的等效实现:

Google AdInline article slot
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$response = file_get_contents('https://geocode-maps.yandex.ru/1.x/?apikey=d3893dc1-c136-4084-b9c-4db26b00463e&geocode=Mohammed+Bin+Rashid+Boulevard+1&lang=en_US&format=json');

$object = json_decode(json: $response, associative: true, flags: JSON_THROW_ON_ERROR);
$data = new AdvancedArrayFactory()->makeAdvancedArray($object);
$formatted = $data
    ->pull("response")
    ->pull("GeoObjectCollection")
    ->pull("featureMember")
    ->pull()
    ->pull("GeoObject")
    ->pull("metaDataProperty")
    ->pull("GeocoderMetaData")
    ->pull("Address")
    ->get("formatted")
    ->default("地址未找到");
$val = $formatted->str();
var_dump($val);
/* 
string(77)
"1, 穆罕默德·本·拉希德大道, 迪拜市中心, 迪拜, 阿拉伯联合酋长国"
*/
$isReal = $formatted->isReal();
var_dump($isReal);
/* bool(true) */

性能基准测试

测试覆盖真实业务场景:JSON 解析(正常路径)、缺失路径处理、元素存在性校验、类型强制转换及原始值获取。

| 使用场景 | 8.4.1(优化前) | 10.4.5(优化后) | 1.2.2(wplake/typed) |

|----------|----------------|----------------|------------------------|

Google AdInline article slot

| JSON 正常路径解析 | 29.210 µs/次 | 6.467 µs/次 | 3.013 µs/次 |

| JSON 缺失路径解析 | 18.716 µs/次 | 5.987 µs/次 | 1.766 µs/次 |

| 元素存在性检查 | 27.237 µs/次 | 6.277 µs/次 | 2.863 µs/次 |

Google AdInline article slot

| 值类型强制转换 | 28.581 µs/次 | 6.740 µs/次 | 2.966 µs/次 |

| 原始值直接获取 | 30.395 µs/次 | 6.558 µs/次 | 3.015 µs/次 |

| 批量提取全部标量值 | 5.897 µs/次 | 1.878 µs/次 | 不支持 |

| 批量提取全部数组 | 7.136 µs/次 | 2.431 µs/次 | 不支持 |

10.4.5 新增特性:批量提取所有标量值与数组——此能力在 wplake/typed 中完全不可用。

核心架构演进

  • 不可变 CommonValue:默认值设定后禁止任何修改,杜绝意外状态污染。
  • 确定性 pull() 行为:从数组中提取时,始终返回首个元素,彻底消除非确定性风险。
  • 精简 API 设计:移除冗余辅助类,将逻辑收敛至单一、连贯的执行流。

因主版本号跃迁(8.4.1 → 10.4.5),向后兼容性在语义上正式中断;但公共 API 接口保持完全一致,现有调用代码无需任何修改。

新增方法与能力

完整链式方法清单:

  • pull(string $key) —— 按键名提取嵌套元素
  • pull() —— 提取数组首个元素(确定性保障)
  • get(string $key) —— 安全取值,自动校验存在性
  • default(mixed $fallback) —— 为缺失值设定默认回退值
  • str() —— 强制转为字符串类型
  • isReal() —— 判定值是否真实存在(非 null / 非空)

复杂场景示例:高效处理结构不稳定、字段可能缺失的第三方 API 响应。

为何值得关注

  • 相比基线性能提升 4 倍,仅比当前性能标杆慢 2 倍
  • 完美保留链式调用的清晰可读性,彻底告别脆弱易错的字符串路径;
  • 独家支持批量提取标量与数组,填补行业空白;
  • 不可变性与确定性设计显著提升系统可靠性与单元测试友好度;
  • 专为中级至高级工程师打造:在生产级性能与强类型安全之间取得最佳平衡。

— Editorial Team

Advertisement 728x90

继续阅读