Skip to content

Commit 86cecb5

Browse files
authored
Merge pull request #44 from JacobBrownAustin/setRule-performance
Speed improvements for `Acl#setRule()`, reducing complexity from `O(N^2)` to `O(N)`
2 parents e0332e1 + 2224633 commit 86cecb5

6 files changed

Lines changed: 884 additions & 55 deletions

File tree

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88
/phpcs.xml export-ignore
99
/phpunit.xml.dist export-ignore
1010
/test/ export-ignore
11+
/benchmarks/ export-ignore
12+
/phpbench.json export-ignore

benchmarks/AclBench.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace LaminasBench\PermissionsAcl;
6+
7+
use Laminas\Permissions\Acl\Acl;
8+
use Laminas\Permissions\Acl\Role\GenericRole;
9+
10+
/**
11+
* @Revs(2)
12+
* @Iterations(2)
13+
* @Warmup(1)
14+
*/
15+
class AclBench
16+
{
17+
private const NUM_ROLES_WITHOUT_PARENT = 135;
18+
private const NUM_ROLES_WITH_PARENT = 70;
19+
private const NUM_RESOURCES = 324;
20+
private const NUM_ALLOW_CALLED = 300;
21+
private const NUM_DENY_CALLED = 300;
22+
23+
private Acl $acl;
24+
25+
public function __construct()
26+
{
27+
$this->acl = new Acl();
28+
}
29+
30+
/**
31+
* Benchmarks setting up ACL with roles and resources, and then adding allow/deny rules to them
32+
*/
33+
public function benchAclRolesResourcesAllowDeny(): void
34+
{
35+
$acl = new Acl();
36+
$role = new GenericRole('A');
37+
$acl->addRole($role);
38+
for ($i = 0; $i < self::NUM_ROLES_WITHOUT_PARENT; $i++) {
39+
$acl->addRole((string) $i);
40+
}
41+
for ($i = 0; $i < self::NUM_ROLES_WITH_PARENT; $i++) {
42+
$acl->addRole((string) ($i + self::NUM_ROLES_WITHOUT_PARENT), $i % self::NUM_ROLES_WITHOUT_PARENT);
43+
}
44+
for ($i = 0; $i < self::NUM_RESOURCES; $i++) {
45+
if ($i === 0) {
46+
$parent = null;
47+
} else {
48+
$parent = (string) (intdiv($i * 3, 2) % $i);
49+
}
50+
$acl->addResource((string) $i, $parent);
51+
}
52+
for ($i = 0; $i < self::NUM_ALLOW_CALLED; $i++) {
53+
$role = (string) (intdiv($i * 3, 2) % (self::NUM_ROLES_WITHOUT_PARENT + self::NUM_ROLES_WITH_PARENT));
54+
if ($i %2 ) {
55+
$resource = (string) (intdiv($i * 7, 5) % self::NUM_RESOURCES);
56+
} else {
57+
$resource = null;
58+
}
59+
$acl->allow($role, $resource);
60+
}
61+
for ($i = 0; $i < self::NUM_DENY_CALLED; $i++) {
62+
$role = (string) (intdiv($i * 13, 11) % (self::NUM_ROLES_WITHOUT_PARENT + self::NUM_ROLES_WITH_PARENT));
63+
if ($i %2 ) {
64+
$resource = (string) (intdiv($i * 19, 17) % self::NUM_RESOURCES);
65+
} else {
66+
$resource = null;
67+
}
68+
$acl->allow($role, $resource);
69+
}
70+
}
71+
}

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"require-dev": {
3535
"laminas/laminas-coding-standard": "~2.5.0",
3636
"laminas/laminas-servicemanager": "^3.19",
37+
"phpbench/phpbench": "^1.2",
3738
"phpunit/phpunit": "^9.5.26",
3839
"psalm/plugin-phpunit": "^0.18.0",
3940
"vimeo/psalm": "^5.0"

0 commit comments

Comments
 (0)