速度提高几百倍,记一次数据结构在实际工作中的运用
上文描述了商品3层选项 尺码-颜色-性别,实现的性能优化过程。
原文实现了选择第一层以后,第二层选项开放,选择第二层以后,第三层选项开放。
我在知乎看到其转载,发现有可以继续改进的方案。
以下方案能实现,任意选择某个选项以后,屏蔽其他层无法选择的项目。
商品各选项分别编码,然后hashcode = a * B * C + b * C + c。
可以建立一个表F,其元素值为二进制位的集合,可以用数值或字符串(因为这是js所以数据结构上不大方便)实现
对于所有(a,b,c)元素,其位标志位
f = (1<<(a+B+C)) | (1<< (b+C)) | (1<<c);
F[hash(a,0,0)] |= f; F[hash(0,b,0)] |= f; F[hash(0,0,c)] |= f;
F[hash(a,b,0)] |= f; F[hash(0,b,c)] |= f; F[hash(a,0,c)] |= f;
另外使F[hash(0,0,0)] |= 全集;
如此,当前任意(a,b,c) (任意项可以未选,只要非全选),查找F[hash(a,b,c)]可得知其可选集合,把相应选项亮起即可。
此方案可选项总数<=31的都很好实现,>=31用数组或字符串代替标量数值。总共ABC个选项如果只有1000多,那简直就是秒杀。
假如数据由后端下发或存储于本地缓存,那么,任意两选择F的元素共有ab + bc + ac, 按9,10,11可选项即服务端发送1011 + 1112 + 1012=232【稀疏】数组即可。232的数组,可以对应990种商品过滤,不过因为每个商品还是需要单独发价格等其他数据。
如果不希望加载网页后立刻要求后端传输所有可能商品,则可以在第一次选择后由后端查找其F(hash(0,b,0)]后将可选位及商品价格传输给前端。
作为后端,可能因商品库存原因要动态删除某个具体商品,上述数据结构并不合适反向删除,但可以改为,F[hash(0,b,0)] = { 选项0被选次数 | 选项1被选次数 | …… }
某具体商品库存不足时,减少其若干个hash的对应选项的次数,将位扩充到数量,即可实现增删。
此方案可存储于数据库(字段类型用pg的原生数组)或json。