Skip to content

Commit

Permalink
Improve Writer speed by precalculating the insert method
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Dec 6, 2024
1 parent 31de31f commit 8cc9dd8
Showing 1 changed file with 17 additions and 12 deletions.
29 changes: 17 additions & 12 deletions src/Writer.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace League\Csv;

use Closure;
use Deprecated;

use function array_map;
Expand Down Expand Up @@ -40,6 +41,8 @@ class Writer extends AbstractCsv implements TabularDataWriter
protected bool $enclose_all = false;
/** @var array{0:array<string>,1:array<string>} */
protected array $enclosure_replace = [[], []];
/** @var Closure(array): (int|false) */
protected Closure $insertRecord;

protected function resetProperties(): void
{
Expand All @@ -49,6 +52,17 @@ protected function resetProperties(): void
[$this->enclosure, $this->escape.$this->enclosure.$this->enclosure],
[$this->enclosure.$this->enclosure, $this->escape.$this->enclosure],
];

$this->insertRecord = fn (array $record): int|false => match ($this->enclose_all) {
true => $this->document->fwrite(implode(
$this->delimiter,
array_map(
fn ($content) => $this->enclosure.$content.$this->enclosure,
str_replace($this->enclosure_replace[0], $this->enclosure_replace[1], $record)
)
).$this->newline),
false => $this->document->fputcsv($record, $this->delimiter, $this->enclosure, $this->escape, $this->newline),
};
}

/**
Expand Down Expand Up @@ -106,21 +120,10 @@ public function insertAll(iterable $records): int
*/
public function insertOne(array $record): int
{
$insert = fn (array $record): int|false => match (true) {
$this->enclose_all => $this->document->fwrite(implode(
$this->delimiter,
array_map(
fn ($content) => $this->enclosure.$content.$this->enclosure,
str_replace($this->enclosure_replace[0], $this->enclosure_replace[1], $record)
)
).$this->newline),
default => $this->document->fputcsv($record, $this->delimiter, $this->enclosure, $this->escape, $this->newline),
};

$record = array_reduce($this->formatters, fn (array $record, callable $formatter): array => $formatter($record), $record);
$this->validateRecord($record);
set_error_handler(fn (int $errno, string $errstr, string $errfile, int $errline) => true);
$bytes = $insert($record);
$bytes = ($this->insertRecord)($record);
restore_error_handler();
if (false === $bytes) {
throw CannotInsertRecord::triggerOnInsertion($record);
Expand Down Expand Up @@ -204,13 +207,15 @@ public function setFlushThreshold(?int $threshold): self
public function relaxEnclosure(): self
{
$this->enclose_all = false;
$this->resetProperties();

return $this;
}

public function forceEnclosure(): self
{
$this->enclose_all = true;
$this->resetProperties();

return $this;
}
Expand Down

0 comments on commit 8cc9dd8

Please sign in to comment.