8000 [String] optimize equalsTo/startsWith/endsWith · tigr1991/symfony@59c215c · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Jan 9, 2025. It is now read-only.

Commit 59c215c

Browse files
committed
[String] optimize equalsTo/startsWith/endsWith
1 parent a306d99 commit 59c215c

File tree

5 files changed

+57
-13
lines changed

5 files changed

+57
-13
lines changed

src/Symfony/Component/String/ByteString.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public function endsWith($suffix): bool
9797
$suffix = (string) $suffix;
9898
}
9999

100-
return \strlen($this->string) - \strlen($suffix) === ($this->ignoreCase ? strripos($this->string, $suffix) : strrpos($this->string, $suffix));
100+
return '' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase);
101101
}
102102

103103
public function equalsTo($string): bool
@@ -362,7 +362,7 @@ public function startsWith($prefix): bool
362362
return parent::startsWith($prefix);
363363
}
364364

365-
return '' !== $prefix && 0 === ($this->ignoreCase ? stripos($this->string, $prefix) : strpos($this->string, $prefix));
365+
return '' !== $prefix && 0 === ($this->ignoreCase ? strncasecmp($this->string, $prefix, \strlen($prefix)) : strncmp($this->string, $prefix, \strlen($prefix)));
366366
}
367367

368368
public function title(bool $allWords = false): parent

src/Symfony/Component/String/CodePointString.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public function endsWith($suffix): bool
9393
return preg_match('{'.preg_quote($suffix).'$}iuD', $this->string);
9494
}
9595

96-
return \strlen($this->string) - \strlen($suffix) === strrpos($this->string, $suffix);
96+
return \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix));
9797
}
9898

9999
public function equalsTo($string): bool
@@ -107,7 +107,7 @@ public function equalsTo($string): bool
107107
}
108108

109109
if ('' !== $string && $this->ignoreCase) {
110-
return mb_strlen($string, 'UTF-8') === mb_strlen($this->string, 'UTF-8') && 0 === mb_stripos($this->string, $string, 0, 'UTF-8');
110+
return \strlen($string) === \strlen($this->string) && 0 === mb_stripos($this->string, $string, 0, 'UTF-8');
111111
}
112112

113113
return $string === $this->string;
@@ -256,6 +256,10 @@ public function startsWith($prefix): bool
256256
return false;
257257
}
258258

259-
return 0 === ($this->ignoreCase ? mb_stripos($this->string, $prefix, 0, 'UTF-8') : strpos($this->string, $prefix));
259+
if ($this->ignoreCase) {
260+
return 0 === mb_stripos($this->string, $prefix, 0, 'UTF-8');
261+
}
262+
263+
return 0 === strncmp($this->string, $prefix, \strlen($prefix));
260264
}
261265
}

src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -859,9 +859,12 @@ public static function provideSnake()
859859
/**
860860
* @dataProvider provideStartsWith
861861
*/
862-
public function testStartsWith(bool $expected, string $origin, $prefix)
862+
public function testStartsWith(bool $expected, string $origin, $prefix, int $form = null)
863863
{
864-
$this->assertSame($expected, static::createFromString($origin)->startsWith($prefix));
864+
$instance = static::createFromString($origin);
865+
$instance = $form ? $instance->normalize($form) : $instance;
866+
867+
$this->assertSame($expected, $instance->startsWith($prefix));
865868
}
866869

867870
public static function provideStartsWith()
@@ -910,9 +913,12 @@ public static function provideStartsWithIgnoreCase()
910913
/**
911914
* @dataProvider provideEndsWith
912915
*/
913-
public function testEndsWith(bool $expected, string $origin, $suffix)
916+
public function testEndsWith(bool $expected, string $origin, $suffix, int $form = null)
914917
{
915-
$this->assertSame($expected, static::createFromString($origin)->endsWith($suffix));
918+
$instance = static::createFromString($origin);
919+
$instance = $form ? $instance->normalize($form) : $instance;
920+
921+
$this->assertSame($expected, $instance->endsWith($suffix));
916922
}
917923

918924
public static function provideEndsWith()

src/Symfony/Component/String/Tests/UnicodeStringTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,26 @@ public static function provideReplaceIgnoreCase(): array
200200
]
201201
);
202202
}
203+
204+
public static function provideStartsWith()
205+
{
206+
return array_merge(
207+
parent::provideStartsWith(),
208+
[
209+
[false, "cle\u{0301} prive\u{0301}e", 'cle', UnicodeString::NFD],
210+
[true, "cle\u{0301} prive\u{0301}e", 'clé', UnicodeString::NFD],
211+
]
212+
);
213+
}
214+
215+
public static function provideEndsWith()
216+
{
217+
return array_merge(
218+
parent::provideEndsWith(),
219+
[
220+
[false, "cle\u{0301} prive\u{0301}e", 'ee', UnicodeString::NFD],
221+
[true, "cle\u{0301} prive\u{0301}e", 'ée', UnicodeString::NFD],
222+
]
223+
);
224+
}
203225
}

src/Symfony/Component/String/UnicodeString.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,15 @@ public function endsWith($suffix): bool
9797
$form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
9898
normalizer_is_normalized($suffix, $form) ?: $suffix = normalizer_normalize($suffix, $form);
9999

100-
if ('' === $suffix || false === $suffix || false === $i = $this->ignoreCase ? grapheme_strripos($this->string, $suffix) : grapheme_strrpos($this->string, $suffix)) {
100+
if ('' === $suffix || false === $suffix) {
101101
return false;
102102
}
103103

104-
return grapheme_strlen($this->string) - grapheme_strlen($suffix) === $i;
104+
if ($this->ignoreCase) {
105+
return 0 === mb_stripos(grapheme_extract($this->string, \strlen($suffix), GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix)), $suffix, 0, 'UTF-8');
106+
}
107+
108+
return $suffix === grapheme_extract($this->string, \strlen($suffix), GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix));
105109
}
106110

107111
public function equalsTo($string): bool
@@ -118,7 +122,7 @@ public function equalsTo($string): bool
118122
normalizer_is_normalized($string, $form) ?: $string = normalizer_normalize($string, $form);
119123

120124
if ('' !== $string && false !== $string && $this->ignoreCase) {
121-
return grapheme_strlen($string) === grapheme_strlen($this->string) && 0 === grapheme_stripos($this->string, $string);
125+
return \strlen($string) === \strlen($this->string) && 0 === mb_stripos($this->string, $string, 0, 'UTF-8');
122126
}
123127

124128
return $string === $this->string;
@@ -332,7 +336,15 @@ public function startsWith($prefix): bool
332336
$form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
333337
normalizer_is_normalized($prefix, $form) ?: $prefix = normalizer_normalize($prefix, $form);
334338

335-
return '' !== $prefix && false !== $prefix && 0 === ($this->ignoreCase ? grapheme_stripos($this->string, $prefix) : grapheme_strpos($this->string, $prefix));
339+
if ('' === $prefix || false === $prefix) {
340+
return false;
341+
}
342+
343+
if ($this->ignoreCase) {
344+
return 0 === mb_stripos(grapheme_extract($this->string, \strlen($prefix), GRAPHEME_EXTR_MAXBYTES), $prefix, 0, 'UTF-8');
345+
}
346+
347+
return $prefix === grapheme_extract($this->string, \strlen($prefix), GRAPHEME_EXTR_MAXBYTES);
336348
}
337349

338350
public function __clone()

0 commit comments

Comments
 (0)
0