Skip to content

Commit e793c96

Browse files
committed
Improve array parser performance
1 parent 9693c1d commit e793c96

File tree

1 file changed

+16
-13
lines changed

1 file changed

+16
-13
lines changed

src/Internal/ArrayParser.php

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ public static function parse(string $data, \Closure $cast, string $delimiter = '
2727
{
2828
$data = \trim($data);
2929

30-
$parser = (new self($data, $cast, $delimiter))->parser();
31-
$data = \iterator_to_array($parser, false);
30+
$parser = new self($data, $cast, $delimiter);
31+
$result = $parser->parseToArray();
3232

33-
if ($parser->getReturn() !== '') {
33+
if ($parser->data !== '') {
3434
throw new PostgresParseException("Data left in buffer after parsing");
3535
}
3636

37-
return $data;
37+
return $result;
3838
}
3939

4040
/**
@@ -50,12 +50,14 @@ private function __construct(
5050
}
5151

5252
/**
53-
* Recursive generator parser yielding array values.
53+
* @return list<mixed> Parsed column data.
5454
*
5555
* @throws PostgresParseException
5656
*/
57-
private function parser(): \Generator
57+
private function parseToArray(): array
5858
{
59+
$result = [];
60+
5961
if ($this->data === '') {
6062
throw new PostgresParseException("Unexpected end of data");
6163
}
@@ -72,13 +74,14 @@ private function parser(): \Generator
7274
}
7375

7476
if ($this->data[0] === '}') { // Empty array
75-
return \ltrim(\substr($this->data, 1));
77+
$this->data = \ltrim(\substr($this->data, 1));
78+
break;
7679
}
7780

7881
if ($this->data[0] === '{') { // Array
79-
$parser = (new self($this->data, $this->cast, $this->delimiter))->parser();
80-
yield \iterator_to_array($parser, false);
81-
$this->data = $parser->getReturn();
82+
$parser = new self($this->data, $this->cast, $this->delimiter);
83+
$result[] = $parser->parseToArray();
84+
$this->data = $parser->data;
8285
$end = $this->trim(0);
8386
continue;
8487
}
@@ -113,15 +116,15 @@ private function parser(): \Generator
113116
$end = $this->trim($position);
114117

115118
if (\strcasecmp($yield, "NULL") === 0) { // Literal NULL is always unquoted.
116-
yield null;
119+
$result[] = null;
117120
continue;
118121
}
119122
}
120123

121-
yield ($this->cast)($yield);
124+
$result[] = ($this->cast)($yield);
122125
} while ($end !== '}');
123126

124-
return $this->data;
127+
return $result;
125128
}
126129

127130
/**

0 commit comments

Comments
 (0)