【问题标题】:Is apcu_fetch() lookup faster with prefix or suffix?apcu_fetch() 使用前缀或后缀查找更快吗?
【发布时间】:2017-02-03 17:50:51
【问题描述】:

场景: - 少量使用 APCu 的 PHP 项目(例如网站)。每个都由唯一的 id / hash 标识,例如20 个字符长。我们在下面称之为$site_hash。 - 每个项目都存储了大量的小值,存储在 APCu 中,由键标识。

通常人们会使用这样的缓存键来区分条目:

$value = apcu_fetch($site_hash . '|' . $key);

但可以改为这样做:

$value = apcu_fetch($key . '|' . $site_hash);

人们可能会认为第二个更快,因为像这样,哈希表查找通常只需要查看前几个字符。

有人可以证实这个假设吗?

(我相信我可以自己进行这个实验。如果可以,我会在这里分享。)

【问题讨论】:

  • 好吧,你没看错。另一方面,您在这里实际上是在谈论毫秒。除非您正在做的事情真正精确、诚实,无论哪种方式都可以。
  • 每个请求可能会被调用 300 次。类加载器的缓存。所以如果我能节省 2 毫秒,我会的。
  • 很公平。 @LeCintas 确实提出了一个很好的观点,无论您如何放置这些键或它们具有什么值,平均查找时间仍然是 O(n)。
  • 为什么是 O(n)?假设 n = 项目数,如果它必须遍历所有元素直到找到匹配项,这将是 O(n)。如果元素存储在查找树中,则为 ~O(log n),这就是此类哈希表的实现方式。但是字符串的长度也有影响。假设 m 是字符串的长度。那么它可能是 O(m + log n) 或 O(m * log n),这取决于它是如何实现的。也许 m 被替换为 k,其中 k
  • 所以唯一完整的答案就是基准测试。

标签: php hashtable apcu


【解决方案1】:

即使函数使用哈希表,您的两种方法都可以比另一种更快。我解释一下:

如果 $site_hash 在 $key 之前使用,那么速度取决于第一个字符的 ASCII 值(如果字符串以 'z' 开头,它会比以 'a' 开头的字符串慢)。

如果以$key开头,问题也会一样。

【讨论】:

  • 那么问题就是平均查找时间。如果我查找 300 个键,如果其中一个键超级快,它也无济于事..
【解决方案2】:

我确实运行了一个基准测试。

<?php

function apcutest($prepend = FALSE) {

  apcu_clear_cache();

  $prefix = $suffix = __FILE__ . __FILE__ . __FILE__;

  $keys = [];
  for ($i = 0; $i < 100000; ++$i) {
    apcu_store(
      $keys[] = $prepend
        ? $prefix . $i
        : $i . $suffix,
      md5("($i)"));
  }

  $t0 = microtime(TRUE);

  foreach ($keys as $key) {

    apcu_fetch($key);
    apcu_fetch($key);
    apcu_fetch($key);
    apcu_fetch($key);
    apcu_fetch($key);

    apcu_fetch($key);
    apcu_fetch($key);
    apcu_fetch($key);
    apcu_fetch($key);
    apcu_fetch($key);
  }

  $t1 = microtime(TRUE);

  return ($t1 - $t0) * 1000;
}

$dts = [];
$dts[] = apcutest(FALSE);
$dts[] = apcutest(TRUE);
$dts[] = apcutest(FALSE);
$dts[] = apcutest(TRUE);
$dts[] = apcutest(FALSE);
$dts[] = apcutest(TRUE);

print_r($dts);

我的机器上的结果:

Array
(
    [0] => 415.98796844482
    [1] => 413.39302062988
    [2] => 414.03603553772
    [3] => 415.08793830872
    [4] => 413.25092315674
    [5] => 414.61896896362
)

观察: 对于一些运行,带有后缀的版本似乎有一个非常小的但一致的优势。 然而,随后的运行并未证实这一点。 对于本实验,两者之间没有统计学上显着的可测量差异。

结论: 根据这个实验,使用前缀还是后缀都没有关系。 这可能不是最终的答案,但这是我目前可以给出的答案。 我想知道这个查找是如何实现的。

【讨论】:

    猜你喜欢
    • 2014-04-30
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2010-10-25
    • 2014-05-30
    • 2017-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多