Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP中std::set的等价物?_Php_C++_Set - Fatal编程技术网

PHP中std::set的等价物?

PHP中std::set的等价物?,php,c++,set,Php,C++,Set,在PHP中,C plus加上“set”的等效函数是什么(“set是一种存储唯一元素的关联容器,元素本身就是其中的键”)?在PHP中,您可以使用它。在PHP中没有内置的与std::set等效的函数 您可以使用“类似”的数组集,但规则的实施取决于您。没有规则,但它们可以 这是链接失效前的一份副本。。全部内容 PHP:arrayvs.SplObjectStorage 我的一个项目QueryPath执行许多需要维护一组唯一对象的任务。在我寻求优化QueryPath的过程中,我一直在研究各种有效存储对象集

在PHP中,C plus加上“set”的等效函数是什么(“set是一种存储唯一元素的关联容器,元素本身就是其中的键”)?

在PHP中,您可以使用它。

在PHP中没有内置的与
std::set
等效的函数


您可以使用“类似”的数组集,但规则的实施取决于您。

没有规则,但它们可以

这是链接失效前的一份副本。。全部内容

PHP:array
vs.
SplObjectStorage

我的一个项目QueryPath执行许多需要维护一组唯一对象的任务。在我寻求优化QueryPath的过程中,我一直在研究各种有效存储对象集的方法,以提供方便的包含检查。换句话说,我需要一个数据结构,它保存一个唯一对象的列表,并且可以快速告诉我该列表中是否存在某个对象。循环浏览列表内容的能力也是必要的

最近,我将候选人名单缩小为两种方法:

使用好的老式数组来模拟散列集。 使用PHP5.2及更高版本中的
SPLObjectStorage
系统。 在直接在
QueryPath
中实现任何东西之前,我首先开始设计这两种方法,然后在Crell的帮助下对这两种方法运行一些微基准测试。说结果令人惊讶是轻描淡写的。基准测试可能会改变我构建未来代码的方式,无论是在
Drupal
内部还是外部

设计

在介绍基准测试之前,我想快速解释一下我确定的两种设计

模拟哈希集的数组

我一直在考虑的第一种方法是使用PHP的标准数组()来模拟由哈希映射支持的集(“哈希集”)。集合是一种数据结构,用于保存唯一元素的列表。在我的例子中,我感兴趣的是存储一组唯一的DOM对象。哈希集是使用哈希表实现的集,其中键是存储值的唯一标识符。虽然人们通常会编写一个类来封装此功能,但我决定将实现作为一个裸阵列进行测试,上面没有任何间接层。换句话说,我将要介绍的是散列集实现的内部结构

目标是:存储一组(唯一的)对象,使它们(a)易于迭代,(b)检查成员资格的成本低廉。 策略:创建一个关联数组,其中键是散列ID,值是对象

有了一个相当好的散列函数,上面概述的策略应该可以正常工作

“相当好的散列函数”——这是第一个问题。如何为像
DOMDocument
这样的对象生成好的哈希函数?一种(不好的)方法是序列化对象,然后,也许,获取其MD5哈希。但是,这在许多对象上都不起作用——特别是不能序列化的任何对象。例如,
DOMDocument
,实际上是由资源支持的,不能序列化

不过,我们需要对这样的函数进行深入研究。事实证明,PHP5中有一个对象哈希函数。它被称为
spl\u object\u hash()
,它可以获取任何对象(即使是非本机PHP的对象)并为其生成hashcode

使用
spl\u object\u hash()。此结构类似于以下内容:

array(
  $hashcode => $object
);
$object = new stdClass();
$hashkey = spl_object_hash($object);
// ...

// Check whether $arr has the $object.
if (isset($arr[$hashkey])) {
  // Do something...
}
例如,我们生成一个如下所示的条目:

$object = new stdClass();
$hashcode = spl_object_hash($object);

$arr = array(
  $hashcode => $object
);
在上面的示例中,hashcode字符串是一个数组键,而对象本身就是数组值。请注意,由于每次对对象重新哈希时哈希代码都是相同的,因此它不仅用作比较点(“如果对象a的哈希键==对象b的哈希键,那么a==b”),还用作唯一性约束。每个数组只能存在一个具有指定哈希代码的对象,因此不可能在数组中放置同一对象的两个副本(实际上是两个引用)

对于这样的数据结构,我们有许多现成的函数来操作该结构,因为我们可以使用所有PHP数组函数。所以在某种程度上,这是一个有吸引力的开箱即用的选择

至少在我们的上下文中,最重要的任务是确定集合中是否存在条目。此检查有两个可能的候选项,并且都需要提供哈希代码:

使用数组\u key\u exists()检查密钥是否存在。 检查是否使用isset()设置了密钥。 直截了当地说,isset()比array_key_exists()快,并且在我们的上下文中提供了相同的特性,因此我们将使用它。(事实上,它们处理空值的方式不同,这对我们来说没有什么区别。不会在集合中插入空值。)

考虑到这一点,我们将使用如下方式执行安全壳检查:

array(
  $hashcode => $object
);
$object = new stdClass();
$hashkey = spl_object_hash($object);
// ...

// Check whether $arr has the $object.
if (isset($arr[$hashkey])) {
  // Do something...
}
同样,使用模拟哈希集的数组允许我们使用所有现有的数组函数,还提供了简单的可重用性。我们可以很容易地将其放入foreach循环并迭代内容。不过,在了解其性能之前,让我们先看看其他可能的解决方案

使用SplObjectStorage

正在考虑的第二种方法使用PHP5.2+中的新
SplObjectStorage
类(可能在5.1中)。此类由C实现支持,为类提供了一种类似集合的存储机制。它强化了独特性;每个对象只能存储一个。它也是可遍历的,因为它实现了Iterable接口。这意味着您可以在foreach之类的循环中使用它。(另一方面,PHP5.2中的版本没有
$objectStore = new SplObjectStorage();
$object = new stdClass();

$objectStore->attach($object);

// ...

if ($objectStore->contains($object)) {
  // Do something...
}
  <?php
  /**
   * Object hashing tests.
   */
  $sos = new SplObjectStorage();

  $docs = array();
  $iterations = 100000;

  for ($i = 0; $i < $iterations; ++$i) {
    $doc = new DOMDocument();
    //$doc = new stdClass();

    $docs[] = $doc;

  }

  $start = $finis = 0;

  $mem_empty = memory_get_usage();

  // Load the SplObjectStorage
  $start = microtime(TRUE);
  foreach ($docs as $d) {
    $sos->attach($d);
  }
  $finis = microtime(TRUE);

  $time_to_fill = $finis - $start;

  // Check membership on the object storage
  $start = microtime(FALSE);
  foreach ($docs as $d) {
    $sos->contains($d);
  }

  $finis = microtime(FALSE);

  $time_to_check = $finis - $start;

  $mem_spl = memory_get_usage();

  $mem_used = $mem_spl - $mem_empty;

  printf("SplObjectStorage:\nTime to fill: %0.12f.\nTime to check: %0.12f.\nMemory: %d\n\n", $time_to_fill, $time_to_check, $mem_used);

  unset($sos);
  $mem_empty = memory_get_usage();

  // Test arrays:
  $start = microtime(TRUE);
  $arr = array();

  // Load the array
  foreach ($docs as $d) {
    $arr[spl_object_hash($d)] = $d;
  }
  $finis = microtime(TRUE);

  $time_to_fill = $finis - $start;

  // Check membership on the array
  $start = microtime(FALSE);
  foreach ($docs as $d) {
    //$arr[spl_object_hash($d)];
    isset($arr[spl_object_hash($d)]);
  }

  $finis = microtime(FALSE);

  $time_to_check = $finis - $start;
  $mem_arr = memory_get_usage();

  $mem_used = $mem_arr - $mem_empty;


  printf("Arrays:\nTime to fill: %0.12f.\nTime to check: %0.12f.\nMemory: %d\n\n", $time_to_fill, $time_to_check, $mem_used);
  ?>
SplObjectStorage:
Time to fill: 0.085041999817.
Time to check: 0.073099000000.
Memory: 6124624



Arrays:
Time to fill: 0.193022966385.
Time to check: 0.153498000000.
Memory: 8524352
SplObjectStorage:
Time to fill: 0.082209110260.
Time to check: 0.070617000000.
Memory: 6124624



Arrays:
Time to fill: 0.189271926880.
Time to check: 0.152644000000.
Memory: 8524360