Skip to content

Commit 8df9a78

Browse files
authored
Merge pull request #18 from worksolutions/dev
increase some performance
2 parents 9d11b99 + 7f939e1 commit 8df9a78

File tree

9 files changed

+80
-64
lines changed

9 files changed

+80
-64
lines changed

composer.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "Collections library for php language",
44
"minimum-stability": "dev",
55
"license": "MIT",
6-
"version": "1.0.4",
6+
"version": "1.0.5",
77
"authors": [
88
{
99
"name": "Maxim Sokolovsky",
@@ -25,11 +25,17 @@
2525
"require-dev": {
2626
"phpunit/phpunit": "^7.5"
2727
},
28+
"suggest": {
29+
"phpbench/phpbench": "Uses only for benchmark purposes"
30+
},
2831
"autoload": {
2932
"psr-4": {"WS\\Utils\\Collections\\": "src/WS/Utils/Collections"}
3033
},
3134
"autoload-dev": {
32-
"psr-4": {"WS\\Utils\\Collections\\": "tests/WS/Utils/Collections"}
35+
"psr-4": {
36+
"WS\\Utils\\Collections\\": "tests/WS/Utils/Collections",
37+
"Benchmarks\\": "benchmarks"
38+
}
3339
},
3440
"scripts": {
3541
"test": [

src/WS/Utils/Collections/AbstractCollection.php

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@
88
abstract class AbstractCollection implements Collection
99
{
1010
protected $elements = [];
11+
protected $pointer = -1;
1112

1213
public function __construct(?array $elements = null)
1314
{
1415
if ($elements === null) {
1516
return;
1617
}
17-
foreach ($elements as $element) {
18-
$this->add($element);
19-
}
18+
$this->setElements($elements);
2019
}
2120

2221
public static function of(...$elements): self
@@ -26,29 +25,36 @@ public static function of(...$elements): self
2625

2726
public function add($element): bool
2827
{
29-
$beforeSize = count($this->elements);
28+
if ($this->pointer === PHP_INT_MAX) {
29+
return false;
30+
}
31+
$this->pointer++;
3032
$this->elements[] = $element;
31-
return $beforeSize < count($this->elements);
33+
return true;
3234
}
3335

3436
public function addAll(iterable $elements): bool
3537
{
36-
$res = true;
3738
foreach ($elements as $element) {
38-
!$this->add($element) && $res = false;
39+
$this->elements[] = $element;
3940
}
40-
return $res;
41+
$newPointer = count($this->elements) - 1;
42+
if ($newPointer > PHP_INT_MAX) {
43+
$this->elements = array_slice($this->elements, 0, $this->pointer);
44+
} else {
45+
$this->pointer = $newPointer;
46+
}
47+
return true;
4148
}
4249

4350
public function merge(Collection $collection): bool
4451
{
45-
$this->elements = array_merge($this->toArray(), $collection->toArray());
46-
return true;
52+
return $this->addAll($collection->toArray());
4753
}
4854

4955
public function clear(): void
5056
{
51-
$this->elements = [];
57+
$this->setElements([]);
5258
}
5359

5460
public function contains($element): bool
@@ -63,17 +69,17 @@ public function equals(Collection $collection): bool
6369

6470
public function size(): int
6571
{
66-
return count($this->elements);
72+
return $this->pointer + 1;
6773
}
6874

6975
public function isEmpty(): bool
7076
{
71-
return !$this->size();
77+
return $this->pointer === -1;
7278
}
7379

7480
public function toArray(): array
7581
{
76-
return array_values($this->elements);
82+
return $this->elements;
7783
}
7884

7985
public function getIterator()
@@ -88,7 +94,8 @@ public function copy(): Collection
8894

8995
protected function setElements(array $elements): void
9096
{
91-
$this->elements = $elements;
97+
$this->elements = array_values($elements);
98+
$this->pointer = count($elements) - 1;
9299
}
93100

94101
protected function getElements(): array

src/WS/Utils/Collections/ArrayList.php

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,8 @@ public function indexOf($element): ?int
3838

3939
public function remove($element): bool
4040
{
41-
$hashCodeRemoved = false;
42-
if ($element instanceof HashCodeAware) {
43-
$hashCodeRemoved = $this->removeThroughHashCode($element);
44-
}
45-
if ($hashCodeRemoved) {
46-
return true;
41+
if (is_object($element) && $element instanceof HashCodeAware) {
42+
return $this->removeThroughHashCode($element);
4743
}
4844
$key = array_search($element, $this->elements, true);
4945
if (false === $key) {
@@ -66,14 +62,20 @@ public function lastIndexOf($element): ?int
6662
public function removeAt(int $index)
6763
{
6864
$size = $this->size();
69-
if (!isset($this->elements[$index]) || $size < $index + 1) {
65+
if ($index >= $size) {
7066
return null;
7167
}
7268

7369
$el = $this->elements[$index];
7470
unset($this->elements[$index]);
75-
$this->elements = array_values($this->elements);
76-
71+
$this->pointer--;
72+
if ($this->pointer === -1) {
73+
return $el;
74+
}
75+
$this->elements = array_merge(
76+
array_slice($this->elements, 0, $index),
77+
array_slice($this->elements, $index)
78+
);
7779
return $el;
7880
}
7981

src/WS/Utils/Collections/ArrayQueue.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public function poll()
2525
throw new RuntimeException('Queue is empty');
2626
}
2727

28+
$this->pointer--;
2829
return array_shift($this->elements);
2930
}
3031

src/WS/Utils/Collections/ArrayStack.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,6 @@ public function peek()
5555
return $this->elements[count($this->elements) - 1];
5656
}
5757

58-
public function merge(Collection $collection): bool
59-
{
60-
$this->elements = array_merge($this->elements, array_values($collection->toArray()));
61-
62-
return true;
63-
}
64-
6558
public function stream(): Stream
6659
{
6760
return new SerialStream($this);

src/WS/Utils/Collections/DummyStreamDecorator.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@ public function reverse(): Stream
108108
return $this;
109109
}
110110

111-
public function reduce(callable $accumulator)
111+
public function reduce(callable $accumulator, $initialValue = null)
112112
{
113-
return $this->decoratedStream->reduce($accumulator);
113+
return $this->decoratedStream->reduce($accumulator, $initialValue);
114114
}
115115

116116
public function limit(int $size): Stream

src/WS/Utils/Collections/SerialStream.php

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ class SerialStream implements Stream
1616

1717
public function __construct(Collection $collection)
1818
{
19-
$this->list = $this->emptyList();
20-
$this->list->addAll($collection);
19+
if ($collection instanceof ListSequence) {
20+
$this->list = $collection->copy();
21+
} else {
22+
$this->list = $this->emptyList();
23+
$this->list->addAll($collection->toArray());
24+
}
2125
}
2226

2327
/**
@@ -220,13 +224,11 @@ public function min(callable $comparator)
220224
return null;
221225
}
222226

223-
$el = $this->findFirst();
227+
$array = $collection->toArray();
224228

225-
if ($collection->size() === 1) {
226-
return $el;
227-
}
229+
$el = array_shift($array);
228230

229-
foreach ($collection as $item) {
231+
foreach ($array as $item) {
230232
if ($comparator($item, $el) < 0) {
231233
$el = $item;
232234
}
@@ -245,13 +247,10 @@ public function max(callable $comparator)
245247
return null;
246248
}
247249

248-
$el = $this->findFirst();
249-
250-
if ($collection->size() === 1) {
251-
return $el;
252-
}
250+
$array = $collection->toArray();
251+
$el = null;
253252

254-
foreach ($collection as $item) {
253+
foreach ($array as $item) {
255254
if ($comparator($item, $el) > 0) {
256255
$el = $item;
257256
}
@@ -263,9 +262,9 @@ public function max(callable $comparator)
263262
/**
264263
* @inheritDoc
265264
*/
266-
public function reduce(callable $accumulator)
265+
public function reduce(callable $accumulator, $initialValue = null)
267266
{
268-
$accumulate = null;
267+
$accumulate = $initialValue;
269268
foreach ($this->list as $item) {
270269
$accumulate = $accumulator($item, $accumulate);
271270
}

src/WS/Utils/Collections/Stream.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,14 @@ public function sortByDesc(callable $extractor): Stream;
126126
* @return Stream
127127
*/
128128
public function reverse(): Stream;
129-
129+
130130
/**
131131
* Reduce collection to single value with accumulator
132-
* @param callable $accumulator
132+
* @param callable $accumulator
133+
* @param null $initialValue
133134
* @return mixed
134135
*/
135-
public function reduce(callable $accumulator);
136+
public function reduce(callable $accumulator, $initialValue = null);
136137

137138
/**
138139
* Limits amount of stream collection elements

tests/WS/Utils/Collections/SerialStreamTest.php

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ private static function fSumAggregator(): callable
3333
};
3434
}
3535

36+
private static function fEmptyFunction(): callable
37+
{
38+
return static function () {};
39+
}
40+
3641
public function createCollection(array $els): Collection
3742
{
3843
return new ArrayList($els);
@@ -207,9 +212,10 @@ public function mapConvertingChecking($input, $modifier, $expected): void
207212
public function reduceCases(): array
208213
{
209214
return [
210-
[[1,2,3], self::fSumAggregator(), 6],
211-
[[1, 2, 4], self::fCountAggregator(), 3],
212-
[[], self::fSumAggregator(), 0]
215+
[[1,2,3], self::fSumAggregator(), 4, 10],
216+
[[1, 2, 4], self::fCountAggregator(), 0, 3],
217+
[[], self::fSumAggregator(), null, null],
218+
[[], self::fEmptyFunction(), [], []]
213219
];
214220
}
215221

@@ -218,15 +224,16 @@ public function reduceCases(): array
218224
* @test
219225
* @param $input
220226
* @param $accumulator
227+
* @param $initialValue
221228
* @param $expected
222229
*/
223-
public function reduceChecking($input, $accumulator, $expected): void
230+
public function reduceChecking($input, $accumulator, $initialValue, $expected): void
224231
{
225232
$actual = $this->createCollection($input)
226233
->stream()
227-
->reduce($accumulator);
234+
->reduce($accumulator, $initialValue);
228235

229-
$this->assertEquals($expected, $actual);
236+
$this->assertSame($expected, $actual);
230237
}
231238

232239
public function aggregateCases(): array
@@ -286,11 +293,11 @@ public function findAnyElementChecking($input): void
286293
public function sortDataSet(): array
287294
{
288295
return [
289-
// input | comparator | min| max | sorted
290-
[[1, 2, 3, 4], self::fIntComparator(), 1, 4, [1, 2, 3, 4]],
291-
[[3, 12, 1, 4], self::fIntComparator(), 1, 12, [1, 3, 4, 12]],
292-
[[], self::fIntComparator(), null, null, []],
293-
[[1], self::fIntComparator(), 1, 1, [1]],
296+
// input | comparator | min | max | sorted
297+
[[1, 2, 3, 4], self::fIntComparator(), 1, 4, [1, 2, 3, 4]],
298+
[[3, 12, 1, 4], self::fIntComparator(), 1, 12, [1, 3, 4, 12]],
299+
[[], self::fIntComparator(), null, null, []],
300+
[[1], self::fIntComparator(), 1, 1, [1]],
294301
];
295302
}
296303

0 commit comments

Comments
 (0)