理解crossfilter.js的篡改代码

Understanding crossfilter.js bit-twiddling hack

本文关键字:代码 crossfilter js 理解      更新时间:2023-09-26

我在crossfilter.js描述中找到了它,我试图理解这行是什么意思

Crossfilter使用排序索引(和一些琐碎的技巧)来使之成为可能,极大地提高了live的性能直方图和top-K列表。

我认为排序索引指的是像数据库中索引的使用。以避免执行全表扫描。每个维度都有一个索引,在索引上执行过滤。这将导致增量过滤(逐个过滤每个索引),最后,当最终生成过滤的数据时,将触发事件。

但是看着代码,我无法理解黑客是什么,它是用来做什么以及如何。谁能解释一下这里的bit- twiding的目的?

开头是这样的声明:

m = 0, // a bit mask representing which dimensions are in use

"位掩码"是一种简单而有效的方法来跟踪true/false选项列表。假设您创建了一个待售汽车的列表,并希望为列出的每辆汽车设置四个额外参数:4x4、ABS、ESP、climatronic。您可以这样定义一个car对象:

MyCar = { brand : "Mercedes", 
          extras : {
              "4x4" : false,
              "ABS" : true,
              "ESP" : false,
              "climatronic" : true
          }
        }

这些额外的是容易设置和检索:if( MyCar.extras['4x4'] ){ /* display a ✓ */ }。它容易,简单,可读,但在某些情况下可能需要太多的资源来处理(想想:在一个巨大的集合上嵌套循环)。

我们可以创建一个数组其中每个索引对应一个特征,对吧?

MyCar = {  brand : "Mercedes",
           // 1: 4x4, 2: ABS, 3: ESP, 4: climatronic
           extras : [ false, true, false, true ]
        }

现在检查给定的汽车是否有4x4你需要使用if( MyCar.extras[0] ){ /* display a ✓ */ }。它的可读性较差(您需要查阅文档以了解哪个特性在哪个索引下),但可能更快,需要更少的内存。

位掩码的概念与之相似,但使用的是数字而不是数组。extras : [ false, true, false, true ]可以缩写为extras : [ 0, 1, 0, 1 ], 0101是数字5的二进制表示。因此,具有描述其特性的位掩码的Car对象可能看起来像这样:

MyCar = {  brand : "Mercedes",
           extras : 5
        }

这看起来完全不直观,但应该非常快速和轻量级。如何检查汽车是否有4x4?那么,4x4表示为1000 (8的二进制表示),因此:

if( !!(MyCar.extras & 8) ){ /* display a ✓ */ }

,现在我们来讨论一下hack,看看这段代码。它真的很简单,但如果你以前没有使用过按位运算符,它看起来很神秘。为了进一步解释:我们的汽车将extras属性设置为5,其二进制为0101,我们想检查最左边的位是否设置为1。按位AND操作返回一个只有在两个操作数都有1时才有1's的数字。

    0101  // 5
AND 1000  // 8
  = 0000 

现在让我们检查ABS,它是左起第2位(0100,即4)。

var hasABS = !!( MyCar.extras & 4 ); // true

因为
    0101  // 5
AND 0100  // 4
  = 0100 

如何设置ESP为true?简单:

MyCar.extras |= 3;  // now extras == 7

发生了什么?二进制OR返回一个具有1's的数字,其中任何一个操作数都具有1位。

5 | 3 = 0101 | 0010 = 0111 = 7;

现在要将ABS设置为false,可以使用

MyCar.extras ^= 4;

我将把二进制XOR的工作留给读者作为练习,但我希望您现在了解使用位掩码和"位摆弄"的要点。