将C函数转换为Javascript

时间:2018-12-05 05:54:21

标签: javascript c algorithm

最终编辑:我错了。 Redis文档中没有任何内容表明计数器只能达到255,即大约一百万。仅在达到100万次点击时,计数器位于255。案例已结案。不用再看了。


我正在尝试将Redis' LFU algorithm从C移植到JS。它使用莫里斯计数器。

常量:

LFU_INIT_VAL = 5。见过here

lfu_log_factor = 10。看过here

找到here的C函数。

/* Logarithmically increment a counter. The greater is the current counter value
 * the less likely is that it gets really implemented. Saturate it at 255. */
uint8_t LFULogIncr(uint8_t counter) {
    if (counter == 255) return 255;
    double r = (double)rand()/RAND_MAX;
    double baseval = counter - LFU_INIT_VAL;
    if (baseval < 0) baseval = 0;
    double p = 1.0/(baseval*server.lfu_log_factor+1);
    if (r < p) counter++;
    return counter;
}

我的JS端口:

LFU_INIT_VAL = 5
lfu_log_factor = 10

function LFULogIncr(counter) {
    if (counter == 255) return 255;
    let r = Math.random();
    let baseval = counter - LFU_INIT_VAL;
    if (baseval < 0) baseval = 0;
    let p = 1.0/(baseval*lfu_log_factor+1);
    if (r < p) counter++;
    return counter;
}

运行算法一百万次,并在计数器增加时记录迭代索引:

let hitFreq = 5
for (let i = 0; i < 1000000; i++) {
    let newHitFreq = LFULogIncr(hitFreq)
    if (newHitFreq > hitFreq) {
        console.log(`New counter: ${newHitFreq}, i = ${i}`)
    }
    hitFreq = newHitFreq
}

基于此表,可以在链接中找到...

+--------+------------+------------+------------+------------+------------+
| factor | 100 hits   | 1000 hits  | 100K hits  | 1M hits    | 10M hits   |
+--------+------------+------------+------------+------------+------------+
| 0      | 104        | 255        | 255        | 255        | 255        |
+--------+------------+------------+------------+------------+------------+
| 1      | 18         | 49         | 255        | 255        | 255        |
+--------+------------+------------+------------+------------+------------+
| 10     | 10         | 18         | 142        | 255        | 255        |
+--------+------------+------------+------------+------------+------------+
| 100    | 8          | 11         | 49         | 143        | 255        |
+--------+------------+------------+------------+------------+------------+

根据上表,在lfu_log_factor为10的情况下,当达到100万次点击时,计数器应为255。但是,当运行我的JS代码时,计数器在约30万次点击中始终达到255。我在做什么错了?

这是一次JS代码运行的结果,将实际匹配数与预期匹配数(factor为10 :)进行了比较:

  • New counter: 10, i = 149(预计〜100,超过49)
  • New counter: 18, i = 652(预计〜1000,低于348)
  • New counter: 142, i = 96383(预计为100k,低于3617)
  • New counter: 255, i = 275361(预计〜1M,低于724,639 !!!)

编辑:嗯...我在C语言中得到的结果与在JS中相同。 255的计数器命中约30万次。

https://onlinegdb.com/Sy8Y8-SJN

表格错误/过时,或者我进行的测试错误,或者代码正确,或者我误解了结果。

0 个答案:

没有答案