属性在 aj 中的内部工作以获得 kdb 中的性能优势

Attributes internal working in aj for performance benefits in kdb

考虑交易 table 't' 并在内存中引用 table 'q':

q)t:([] sym:`GOOG`AMZN`GOOG`AMZN; time:10:01 10:02 10:02 10:03; px:10 20 11 19)
q)q:([] sym:`GOOG`AMZN`AMZN`GOOG`AMZN; time:10:01 10:01 10:02 10:02 10:03; vol:100 200 210 110 220)

为了获得性能优势,在 q table 的 'sym' 列上应用分组属性并使 'time' 列在 sym.
中排序 使用它,我可以清楚地看到它带来的性能优势:

q)\t:1000000 aj[`sym`time;t;q]
9573
q)\t:1000000 aj[`sym`time;t;q1]
8761
q)\t:100000 aj[`sym`time;t;q]
968
q)\t:100000 aj[`sym`time;t;q1]
893

并且在大型 tables 中性能要好得多。

现在,我试图了解当我们将分组属性应用于 sym 列并在 sym 中对时间进行排序时它在内部是如何工作的。

我的理解是内部 aj 应该以下面的方式发生,有人可以让我知道正确的内部工作吗?
* 因为,grouped 属性应用于 sym;所以它为 table q1 创建了一个散列 table,然后因为我们按时间排序所以内部 q1 table 可能看起来像。

GOOG|(10:01;10:02)|(100;110)
AMZN|(10:01;10:02:10:03)|(200;210;220)

因此在 q1 的情况下,如果解释器必须加入 (AMZN;10:02) of t table;它会在更短的时间内直接在 q1 的 hasttable 中找到它,但是为了在 table [=28= 中加入 table 't' 的相同值(AMZN;10:02) ] 解释器将不得不通过 table 'q' 进行线性搜索,因此需要更多时间。

我相信您走在正确的轨道上,但我们无法确定,因为我们无法访问 kdb 源代码以准确了解它的作用。

如果您查看 aj 的定义,您会发现它基于 bin:

q)aj
k){.Q.ft[{d:x_z;$[&/j:-1<i:(x#z)bin x#y;y,'d i;+.[+.Q.ff[y]d;(!+d;j);:;.+d i j:&j]]}[x,();;0!z]]y}

具体来说,

(`sym`time#q)bin `sym`time#t

bin 文档提供了有关 bin 行为方式的更多详细信息:https://code.kx.com/q/ref/bin/

我相信在双列的情况下,它将首先在 sym 列上匹配,然后在第二列上使用 bin。就像你说的那样,sym 上的分组属性加快了 syms 部分的匹配,并且按时排序确保了 bin returns 正确的结果。请注意,对于磁盘查询,最好将 `p# 放在 sym 而不是 `g# 上,因为 parted 属性对于来自磁盘的 sym matching/retrieving 是最佳的。