Time complexity 在编写代码复杂性方面的JQ查询时,常见的陷阱是什么?有分析工具吗?

Time complexity 在编写代码复杂性方面的JQ查询时,常见的陷阱是什么?有分析工具吗?,time-complexity,query-optimization,jq,Time Complexity,Query Optimization,Jq,我有一个300行的JQ代码,在我处理的文件上运行(字面上是几个小时)(简单的列表是200K-2.5M JSON对象,500MB-6GB大小) 乍一看,代码的复杂度看起来是线性的,但我很容易错过一些东西 在JQ的代码复杂性方面,是否有最常见的陷阱需要注意?或者使用一些工具来识别代码中的关键瓶颈 我有点不愿意公开我的代码,一方面是因为它的大小和复杂性,另一方面是因为它有点专有性 对输入文件进行修剪,以仅保留最相关的对象,并对其进行预压缩,以仅保留所需的字段,这是优化处理流程的明显步骤。我想知道在查询

我有一个300行的JQ代码,在我处理的文件上运行(字面上是几个小时)(简单的列表是200K-2.5M JSON对象,500MB-6GB大小)

乍一看,代码的复杂度看起来是线性的,但我很容易错过一些东西

在JQ的代码复杂性方面,是否有最常见的陷阱需要注意?或者使用一些工具来识别代码中的关键瓶颈

我有点不愿意公开我的代码,一方面是因为它的大小和复杂性,另一方面是因为它有点专有性


对输入文件进行修剪,以仅保留最相关的对象,并对其进行预压缩,以仅保留所需的字段,这是优化处理流程的明显步骤。我想知道在查询复杂性方面可以具体做些什么。

由于您显然不是初学者,犯初学者错误的可能性似乎很小,因此如果您无法找到一种方法来共享有关程序和数据的一些详细信息,您可以尝试 分解程序,以便查看计算资源的消耗情况。在这方面,适当的
debug
语句可能会有所帮助

以下用于计算已用时钟时间的过滤器也可能有用:

def time(f):
  now as $start | f as $out | (now - $start | stderr) | "", $out;

def time(f; $msg):
  now as $start | f as $out | ("\(now - $start): \($msg)" | stderr) | "", $out;

例子 输出:

["DEBUG:",1021]
0.7642250061035156
1021

通常,花费比预期时间更长的程序也会产生不正确的结果,因此可能首先要检查结果是否正确。如果是,那么以下内容可能值得检查:

  • 避免口吃(即,优先使用
    输入
    和/或
    输入
  • 当心arity大于0的函数调用自己
  • 避免不必要地重新计算中间结果,例如,将它们存储在$-变量中,或将它们包含在过滤器的输入中
  • 尽可能使用具有“短路”语义的函数,尤其是
    any
    all
  • 根据需要使用
    limit/2
    first/1
    ,和/或
    foreach
  • 在数组上实现
    index/1
    对于大型数组来说可能是个问题,因为它首先计算所有索引
  • 请记住,
    unique
    groupby
    应小心使用,因为两者都涉及
    排序
  • 使用
    b搜索
    插入排序数组中的项目并对其进行二进制搜索
  • 使用JSON对象作为字典通常是一个好主意
还要注意,流式解析器(使用--stream选项调用)的设计目的是在时间和空间之间进行权衡,以利于后者。成功了


最后,jq是面向流的,使用流有时比使用数组更有效。

避免不必要地重新计算中间结果,例如将它们存储在$-变量中,或将它们包含在筛选器的输入中。-我想知道什么算是“重新计算”。我经常将中间结果存储为$variables;它们的尺寸很小,但有些理论上需要对整个输入进行全扫描;以后计算的变量取决于之前准备的值。这里有任何超出限制的建议/2吗?我的原始输入按我选择的键进行了保证排序(使用index/1和select(key==value/>value/No)。请参见builtin.jq()有关内置函数的定义。请注意内置B搜索。另请参阅有关unique、group by、index和stream-orientation的更新。您可以使用中定义的GROUPS by;您可能还希望查看jq Cookbook中的一些食谱(谷歌术语:
jq
Cookbook
["DEBUG:",1021]
0.7642250061035156
1021