Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd075d0c

Browse files
committed
feature#27563 [Cache] Improve perf of array-based pools (nicolas-grekas)
This PR was merged into the 4.2-dev branch.Discussion----------[Cache] Improve perf of array-based pools| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | no| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets | -| License | MIT| Doc PR | -- skip key validation when key is already known- remove overhead in `ArrayCache::get()` via inlining- don't store simple values in serialized format when not needed, preserving COW~~Needs#27565 to be green.~~Commits-------92a2d47 [Cache] Improve perf of array-based pools
2 parents137dd76 +92a2d47 commitd075d0c

File tree

4 files changed

+110
-63
lines changed

4 files changed

+110
-63
lines changed

‎src/Symfony/Component/Cache/Adapter/ArrayAdapter.php‎

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,10 @@ function ($key, $value, $isHit) use ($defaultLifetime) {
5656
*/
5757
publicfunctiongetItem($key)
5858
{
59-
$isHit =$this->hasItem($key);
60-
try {
61-
if (!$isHit) {
62-
$this->values[$key] =$value =null;
63-
}elseif (!$this->storeSerialized) {
64-
$value =$this->values[$key];
65-
}elseif ('b:0;' ===$value =$this->values[$key]) {
66-
$value =false;
67-
}elseif (false ===$value =unserialize($value)) {
68-
$this->values[$key] =$value =null;
69-
$isHit =false;
70-
}
71-
}catch (\Exception$e) {
72-
CacheItem::log($this->logger,'Failed to unserialize key "{key}"',array('key' =>$key,'exception' =>$e));
59+
if (!$isHit =$this->hasItem($key)) {
7360
$this->values[$key] =$value =null;
74-
$isHit =false;
61+
}else {
62+
$value =$this->storeSerialized ?$this->unfreeze($key,$isHit) :$this->values[$key];
7563
}
7664
$f =$this->createCacheItem;
7765

@@ -84,7 +72,9 @@ public function getItem($key)
8472
publicfunctiongetItems(array$keys =array())
8573
{
8674
foreach ($keysas$key) {
87-
CacheItem::validateKey($key);
75+
if (!\is_string($key) || !isset($this->expiries[$key])) {
76+
CacheItem::validateKey($key);
77+
}
8878
}
8979

9080
return$this->generateItems($keys,microtime(true),$this->createCacheItem);
@@ -120,15 +110,8 @@ public function save(CacheItemInterface $item)
120110

121111
returntrue;
122112
}
123-
if ($this->storeSerialized) {
124-
try {
125-
$value =serialize($value);
126-
}catch (\Exception$e) {
127-
$type =is_object($value) ?get_class($value) :gettype($value);
128-
CacheItem::log($this->logger,'Failed to save key "{key}" ({type})',array('key' =>$key,'type' =>$type,'exception' =>$e));
129-
130-
returnfalse;
131-
}
113+
if ($this->storeSerialized &&null ===$value =$this->freeze($value)) {
114+
returnfalse;
132115
}
133116
if (null ===$expiry &&0 <$item["\0*\0defaultLifetime"]) {
134117
$expiry =microtime(true) +$item["\0*\0defaultLifetime"];

‎src/Symfony/Component/Cache/Simple/ArrayCache.php‎

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,20 @@ public function __construct(int $defaultLifetime = 0, bool $storeSerialized = tr
4545
*/
4646
publicfunctionget($key,$default =null)
4747
{
48-
foreach ($this->getMultiple(array($key),$default)as$v) {
49-
return$v;
48+
if (!\is_string($key) || !isset($this->expiries[$key])) {
49+
CacheItem::validateKey($key);
50+
}
51+
if (!$isHit =isset($this->expiries[$key]) && ($this->expiries[$key] >microtime(true) || !$this->delete($key))) {
52+
$this->values[$key] =null;
53+
54+
return$default;
55+
}
56+
if (!$this->storeSerialized) {
57+
return$this->values[$key];
5058
}
59+
$value =$this->unfreeze($key,$isHit);
60+
61+
return$isHit ?$value :$default;
5162
}
5263

5364
/**
@@ -61,7 +72,9 @@ public function getMultiple($keys, $default = null)
6172
thrownewInvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given',is_object($keys) ?get_class($keys) :gettype($keys)));
6273
}
6374
foreach ($keysas$key) {
64-
CacheItem::validateKey($key);
75+
if (!\is_string($key) || !isset($this->expiries[$key])) {
76+
CacheItem::validateKey($key);
77+
}
6578
}
6679

6780
return$this->generateItems($keys,microtime(true),function ($k,$v,$hit)use ($default) {return$hit ?$v :$default; });
@@ -87,7 +100,9 @@ public function deleteMultiple($keys)
87100
*/
88101
publicfunctionset($key,$value,$ttl =null)
89102
{
90-
CacheItem::validateKey($key);
103+
if (!\is_string($key)) {
104+
CacheItem::validateKey($key);
105+
}
91106

92107
return$this->setMultiple(array($key =>$value),$ttl);
93108
}
@@ -103,27 +118,20 @@ public function setMultiple($values, $ttl = null)
103118
$valuesArray =array();
104119

105120
foreach ($valuesas$key =>$value) {
106-
\is_int($key) || CacheItem::validateKey($key);
121+
if (!\is_int($key) && !(\is_string($key) &&isset($this->expiries[$key]))) {
122+
CacheItem::validateKey($key);
123+
}
107124
$valuesArray[$key] =$value;
108125
}
109126
if (false ===$ttl =$this->normalizeTtl($ttl)) {
110127
return$this->deleteMultiple(array_keys($valuesArray));
111128
}
112-
if ($this->storeSerialized) {
113-
foreach ($valuesArrayas$key =>$value) {
114-
try {
115-
$valuesArray[$key] =serialize($value);
116-
}catch (\Exception$e) {
117-
$type =is_object($value) ?get_class($value) :gettype($value);
118-
CacheItem::log($this->logger,'Failed to save key "{key}" ({type})',array('key' =>$key,'type' =>$type,'exception' =>$e));
119-
120-
returnfalse;
121-
}
122-
}
123-
}
124129
$expiry =0 <$ttl ?microtime(true) +$ttl :PHP_INT_MAX;
125130

126131
foreach ($valuesArrayas$key =>$value) {
132+
if ($this->storeSerialized &&null ===$value =$this->freeze($value)) {
133+
returnfalse;
134+
}
127135
$this->values[$key] =$value;
128136
$this->expiries[$key] =$expiry;
129137
}

‎src/Symfony/Component/Cache/Tests/Adapter/ArrayAdapterTest.php‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ public function testGetValuesHitAndMiss()
3636

3737
// Hit
3838
$item =$cache->getItem('foo');
39-
$item->set('4711');
39+
$item->set('::4711');
4040
$cache->save($item);
4141

4242
$fooItem =$cache->getItem('foo');
4343
$this->assertTrue($fooItem->isHit());
44-
$this->assertEquals('4711',$fooItem->get());
44+
$this->assertEquals('::4711',$fooItem->get());
4545

4646
// Miss (should be present as NULL in $values)
4747
$cache->getItem('bar');
@@ -50,7 +50,7 @@ public function testGetValuesHitAndMiss()
5050

5151
$this->assertCount(2,$values);
5252
$this->assertArrayHasKey('foo',$values);
53-
$this->assertSame(serialize('4711'),$values['foo']);
53+
$this->assertSame(serialize('::4711'),$values['foo']);
5454
$this->assertArrayHasKey('bar',$values);
5555
$this->assertNull($values['bar']);
5656
}

‎src/Symfony/Component/Cache/Traits/ArrayTrait.php‎

Lines changed: 74 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,34 @@ trait ArrayTrait
3434
*/
3535
publicfunctiongetValues()
3636
{
37-
return$this->values;
37+
if (!$this->storeSerialized) {
38+
return$this->values;
39+
}
40+
41+
$values =$this->values;
42+
foreach ($valuesas$k =>$v) {
43+
if (null ===$v ||'N;' ===$v) {
44+
continue;
45+
}
46+
if (!\is_string($v) || !isset($v[2]) ||':' !==$v[1]) {
47+
$values[$k] =serialize($v);
48+
}
49+
}
50+
51+
return$values;
3852
}
3953

4054
/**
4155
* {@inheritdoc}
4256
*/
4357
publicfunctionhasItem($key)
4458
{
59+
if (\is_string($key) &&isset($this->expiries[$key]) &&$this->expiries[$key] >microtime(true)) {
60+
returntrue;
61+
}
4562
CacheItem::validateKey($key);
4663

47-
returnisset($this->expiries[$key]) &&($this->expiries[$key] >microtime(true) ||!$this->deleteItem($key));
64+
returnisset($this->expiries[$key]) && !$this->deleteItem($key);
4865
}
4966

5067
/**
@@ -62,8 +79,9 @@ public function clear()
6279
*/
6380
publicfunctiondeleteItem($key)
6481
{
65-
CacheItem::validateKey($key);
66-
82+
if (!\is_string($key) || !isset($this->expiries[$key])) {
83+
CacheItem::validateKey($key);
84+
}
6785
unset($this->values[$key],$this->expiries[$key]);
6886

6987
returntrue;
@@ -80,21 +98,10 @@ public function reset()
8098
privatefunctiongenerateItems(array$keys,$now,$f)
8199
{
82100
foreach ($keysas$i =>$key) {
83-
try {
84-
if (!$isHit =isset($this->expiries[$key]) && ($this->expiries[$key] >$now || !$this->deleteItem($key))) {
85-
$this->values[$key] =$value =null;
86-
}elseif (!$this->storeSerialized) {
87-
$value =$this->values[$key];
88-
}elseif ('b:0;' ===$value =$this->values[$key]) {
89-
$value =false;
90-
}elseif (false ===$value =unserialize($value)) {
91-
$this->values[$key] =$value =null;
92-
$isHit =false;
93-
}
94-
}catch (\Exception$e) {
95-
CacheItem::log($this->logger,'Failed to unserialize key "{key}"',array('key' =>$key,'exception' =>$e));
101+
if (!$isHit =isset($this->expiries[$key]) && ($this->expiries[$key] >$now || !$this->deleteItem($key))) {
96102
$this->values[$key] =$value =null;
97-
$isHit =false;
103+
}else {
104+
$value =$this->storeSerialized ?$this->unfreeze($key,$isHit) :$this->values[$key];
98105
}
99106
unset($keys[$i]);
100107

@@ -105,4 +112,53 @@ private function generateItems(array $keys, $now, $f)
105112
yield$key =>$f($key,null,false);
106113
}
107114
}
115+
116+
privatefunctionfreeze($value)
117+
{
118+
if (null ===$value) {
119+
return'N;';
120+
}
121+
if (\is_string($value)) {
122+
// Serialize strings if they could be confused with serialized objects or arrays
123+
if ('N;' ===$value || (isset($value[2]) &&':' ===$value[1])) {
124+
returnserialize($value);
125+
}
126+
}elseif (!\is_scalar($value)) {
127+
try {
128+
$serialized =serialize($value);
129+
}catch (\Exception$e) {
130+
$type =is_object($value) ?get_class($value) :gettype($value);
131+
CacheItem::log($this->logger,'Failed to save key "{key}" ({type})',array('key' =>$key,'type' =>$type,'exception' =>$e));
132+
133+
return;
134+
}
135+
// Keep value serialized if it contains any objects or any internal references
136+
if ('C' ===$serialized[0] ||'O' ===$serialized[0] ||preg_match('/;[OCRr]:[1-9]/',$serialized)) {
137+
return$serialized;
138+
}
139+
}
140+
141+
return$value;
142+
}
143+
144+
privatefunctionunfreeze(string$key,bool &$isHit)
145+
{
146+
if ('N;' ===$value =$this->values[$key]) {
147+
returnnull;
148+
}
149+
if (\is_string($value) &&isset($value[2]) &&':' ===$value[1]) {
150+
try {
151+
$value =unserialize($value);
152+
}catch (\Exception$e) {
153+
CacheItem::log($this->logger,'Failed to unserialize key "{key}"',array('key' =>$key,'exception' =>$e));
154+
$value =false;
155+
}
156+
if (false ===$value) {
157+
$this->values[$key] =$value =null;
158+
$isHit =false;
159+
}
160+
}
161+
162+
return$value;
163+
}
108164
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp