Skip to content

Commit

Permalink
Speed up JsonConverter again
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Oct 15, 2024
1 parent 474b613 commit af73e22
Showing 1 changed file with 16 additions and 13 deletions.
29 changes: 16 additions & 13 deletions src/JsonConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ final class JsonConverter
public readonly int $depth;
/** @var int<1, max> */
public readonly int $indentSize;
/** @var Closure(T, array-key): mixed */
public readonly Closure $formatter;
/** @var ?Closure(T, array-key): mixed */
public readonly ?Closure $formatter;
/** @var int<1, max> */
public readonly int $chunkSize;
/** @var non-empty-string */
Expand All @@ -127,20 +127,20 @@ public static function create(): self
flags: 0,
depth: 512,
indentSize: 4,
formatter: fn (mixed $value, int|string $offset) => $value,
formatter: null,
chunkSize: 500
);
}

/**
* @param int<1, max> $depth
* @param int<1, max> $indentSize
* @param Closure(T, array-key): mixed $formatter
* @param ?Closure(T, array-key): mixed $formatter
* @param int<1, max> $chunkSize
*
* @throws InvalidArgumentException
*/
private function __construct(int $flags, int $depth, int $indentSize, Closure $formatter, int $chunkSize)
private function __construct(int $flags, int $depth, int $indentSize, ?Closure $formatter, int $chunkSize)
{
json_encode([], $flags & ~JSON_THROW_ON_ERROR, $depth);

Expand Down Expand Up @@ -347,8 +347,6 @@ public function chunkSize(int $chunkSize): self
*/
public function formatter(?Closure $formatter): self
{
$formatter ??= fn (mixed $value, int|string $offset) => $value;

return new self($this->flags, $this->depth, $this->indentSize, $formatter, $this->chunkSize);
}

Expand Down Expand Up @@ -444,32 +442,37 @@ public function save(iterable $records, mixed $destination, $context = null): in
*/
public function convert(iterable $records): Iterator
{
$iterator = MapIterator::fromIterable($records, $this->formatter);
$iterator = match ($this->formatter) {
null => MapIterator::toIterator($records),
default => MapIterator::fromIterable($records, $this->formatter)
};

$iterator->rewind();
if (!$iterator->valid()) {
yield $this->emptyIterable;

return;
}

$incr = 0;
$chunk = [];
$chunkOffset = 0;
$offset = 0;
$current = $iterator->current();
$iterator->next();

yield $this->start;

while ($iterator->valid()) {
if ($incr === $this->chunkSize) {
if ($chunkOffset === $this->chunkSize) {
yield ($this->jsonEncodeChunk)($chunk).$this->separator;

$incr = 0;
$chunkOffset = 0;
$chunk = [];
}

++$incr;
$chunk[++$offset] = $current;
$chunk[$offset] = $current;
++$chunkOffset;
++$offset;
$current = $iterator->current();
$iterator->next();
}
Expand Down

0 comments on commit af73e22

Please sign in to comment.