You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化Jsonata计算连续记录时间差的性能?

优化Jsonata数组处理性能:添加elapsed属性

需求说明

我有一个每个对象都包含timestamp属性的数组,需要为数组中的每个对象添加名为elapsed的属性:

  • 第一条记录的elapsed值为当前时间($millis())与该记录timestamp的毫秒差
  • 后续记录的elapsed值为当前记录与前一条记录timestamp的毫秒差

现有代码功能正常,但处理数千条记录时速度极慢,希望通过缓存每次迭代中的timestamp值,避免重复从数组中获取$a[$i-1].timestamp来提升性能。

测试数据

{"events":[
  {
    "a": "alpha",
    "b": "beta",
    "counting": 1,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780031105
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 2,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780031532
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 3,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780032058
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 4,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780032544
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 5,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780033056
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 6,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780033559
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 7,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780034034
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 8,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780034564
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 9,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780035036
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 10,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780035589
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 11,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780036035
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 12,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780036564
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 13,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780037036
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 14,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780037559
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 15,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780038059
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 16,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780038560
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 17,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780039066
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 18,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780039538
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 19,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780040061
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 20,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780040567
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 21,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780041039
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 22,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780041561
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 23,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780042050
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 24,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780042567
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 25,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780043040
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 26,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780043567
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 27,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780044041
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 28,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780044606
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 29,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780045040
  },
  {
    "a": "alpha",
    "b": "beta",
    "counting": 30,
    "_event": "node:c6cc8e092ff036f1-ff15099a3bf7ad90",
    "timestamp": 1740780045560
  }
]}

现有代码

$map(events, 
    function($v, $i, $a){
        $v ~> |$|
        {
            "elapsed" :  $i = 0 ? 
            ($millis() - $v.timestamp) : 
            $v.timestamp - $a[$i-1].timestamp
        }|
    }
)

优化方案

使用$reduce替代$map,利用$reduce的累加器维护迭代状态(缓存前一条记录的timestamp),避免每次迭代都去原数组中查找前一个元素,大幅降低大数组处理的性能开销。

优化后的代码

$reduce(events, function($accumulator, $current) {
    // 计算当前记录的elapsed值
    $elapsed := $accumulator.previousTimestamp = null ? 
        ($millis() - $current.timestamp) : 
        ($current.timestamp - $accumulator.previousTimestamp);
    
    // 为当前记录添加elapsed属性
    $newRecord := $current ~> |$| { "elapsed": $elapsed }|;
    
    // 更新累加器:追加新记录到结果数组,缓存当前timestamp
    {
        "result": $append($accumulator.result, [$newRecord]),
        "previousTimestamp": $current.timestamp
    }
}, { "result": [], "previousTimestamp": null }).result

优化点说明

  1. 状态缓存:通过累加器的previousTimestamp字段缓存上一条记录的时间戳,每次迭代直接使用该值,无需再通过数组索引查找前一个元素,消除了数组索引访问的性能损耗。
  2. 单次遍历:$reduce仅需遍历数组一次,而原$map在每次迭代时都要额外访问数组的前一个元素,相当于对数组进行了多次隐式访问。
  3. 逻辑清晰:将状态维护和记录处理逻辑整合在一次迭代中,代码可读性和执行效率都得到提升。

内容的提问来源于stack exchange,提问作者Shimbone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 03:23:09