From df993ab48449f4f21de3d1f6f3d6bd1ca177216f Mon Sep 17 00:00:00 2001 From: Fred Emmott Date: Wed, 1 May 2019 15:30:43 -0700 Subject: [PATCH] Add methods for the kind of op instead of using `is` expressions (#18) Summary: This is a > 75% speedup for `getUnifiedDiff(string $a, string $b)` on large files when not running in repo-auth mode. Pull Request resolved: https://github.com/hhvm/difflib/pull/18 Reviewed By: pittsw Differential Revision: D15170438 Pulled By: fredemmott fbshipit-source-id: ec5cd8e2d59951b2e5fe7aa637c29f740d0630d8 --- src/CLIColoredUnifiedDiff.php | 8 ++++---- src/ColoredUnifiedDiff.php | 4 ++-- src/DiffDeleteOp.php | 5 +++++ src/DiffInsertOp.php | 5 +++++ src/DiffKeepOp.php | 5 +++++ src/DiffOp.php | 12 ++++++++++++ src/StringDiff.php | 15 +++++++++------ src/cluster.php | 11 ++++++----- 8 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/CLIColoredUnifiedDiff.php b/src/CLIColoredUnifiedDiff.php index 7766242..c0eb98d 100644 --- a/src/CLIColoredUnifiedDiff.php +++ b/src/CLIColoredUnifiedDiff.php @@ -70,11 +70,11 @@ final protected static function colorDeleteLineWithIntralineEdits( ): string { $line = self::DELETE_COLOR.'-'; foreach ($ops as $op) { - if ($op is DiffKeepOp<_>) { + if ($op->isKeepOp()) { $line .= $op->getContent(); continue; } - if ($op is DiffDeleteOp<_>) { + if ($op->isDeleteOp()) { $line .= self::INTRALINE_DELETE_COLOR. $op->getContent(). self::RESET. @@ -91,11 +91,11 @@ final protected static function colorInsertLineWithIntralineEdits( ): string { $line = self::INSERT_COLOR.'+'; foreach ($ops as $op) { - if ($op is DiffKeepOp<_>) { + if ($op->isKeepOp()) { $line .= $op->getContent(); continue; } - if ($op is DiffInsertOp<_>) { + if ($op->isInsertOp()) { $line .= self::INTRALINE_INSERT_COLOR. $op->getContent(). self::RESET. diff --git a/src/ColoredUnifiedDiff.php b/src/ColoredUnifiedDiff.php index 16b6c6a..d073328 100644 --- a/src/ColoredUnifiedDiff.php +++ b/src/ColoredUnifiedDiff.php @@ -116,10 +116,10 @@ final public static function create( $words_next = vec(\preg_split('/([^a-zA-Z0-9_]+)/', $next, -1, \PREG_SPLIT_DELIM_CAPTURE)); $intraline = (new StringDiff($words_line, $words_next))->getDiff(); $out[] = $intraline - |> Vec\filter($$, $op ==> !$op is DiffInsertOp<_>) + |> Vec\filter($$, $op ==> !$op->isInsertOp()) |> static::colorDeleteLineWithIntralineEdits($$); $out[] = $intraline - |> Vec\filter($$, $op ==> !$op is DiffDeleteOp<_>) + |> Vec\filter($$, $op ==> !$op->isDeleteOp()) |> static::colorInsertLineWithIntralineEdits($$); continue; } diff --git a/src/DiffDeleteOp.php b/src/DiffDeleteOp.php index f215c60..5fed0ad 100644 --- a/src/DiffDeleteOp.php +++ b/src/DiffDeleteOp.php @@ -27,6 +27,11 @@ public function getContent(): TContent { return $this->content; } + <<__Override>> + public function isDeleteOp(): bool { + return true; + } + <<__Override>> public function asDeleteOp(): DiffDeleteOp { return $this; diff --git a/src/DiffInsertOp.php b/src/DiffInsertOp.php index 4536050..ff9d605 100644 --- a/src/DiffInsertOp.php +++ b/src/DiffInsertOp.php @@ -27,6 +27,11 @@ public function getContent(): TContent { return $this->content; } + <<__Override>> + public function isInsertOp(): bool { + return true; + } + <<__Override>> public function asInsertOp(): DiffInsertOp { return $this; diff --git a/src/DiffKeepOp.php b/src/DiffKeepOp.php index 76741ca..24affc2 100644 --- a/src/DiffKeepOp.php +++ b/src/DiffKeepOp.php @@ -32,6 +32,11 @@ public function getContent(): TContent { return $this->content; } + <<__Override>> + public function isKeepOp(): bool { + return true; + } + <<__Override>> public function asKeepOp(): DiffKeepOp { return $this; diff --git a/src/DiffOp.php b/src/DiffOp.php index 82a4148..f2bf190 100644 --- a/src/DiffOp.php +++ b/src/DiffOp.php @@ -18,6 +18,18 @@ abstract class DiffOp { abstract public function getContent(): TContent; + public function isDeleteOp(): bool { + return false; + } + + public function isInsertOp(): bool { + return false; + } + + public function isKeepOp(): bool { + return false; + } + public function asDeleteOp(): DiffDeleteOp { invariant_violation('not a deletion'); } diff --git a/src/StringDiff.php b/src/StringDiff.php index 0bcbf2d..8c73a79 100644 --- a/src/StringDiff.php +++ b/src/StringDiff.php @@ -40,12 +40,12 @@ public function getHunks(int $context): vec>> { $remaining = $this->getDiff(); $last = C\lastx($remaining); // diff -u ignores trailing newlines - if ($last is DiffKeepOp<_> && $last->getContent() === '') { + if ($last->isKeepOp() && $last->getContent() === '') { $remaining = Vec\slice($remaining, 0, C\count($remaining) - 1); } while (!C\is_empty($remaining)) { - $not_keep = C\find_key($remaining, $row ==> !$row is DiffKeepOp<_>); + $not_keep = C\find_key($remaining, $row ==> !$row->isKeepOp()); if ($not_keep === null) { break; } @@ -57,7 +57,7 @@ public function getHunks(int $context): vec>> { $end = $count; $run_start = null; for ($i = $context; $i < $count; ++$i) { - if ($remaining[$i] is DiffKeepOp<_>) { + if ($remaining[$i]->isKeepOp()) { $run_start ??= $i; continue; } @@ -101,7 +101,8 @@ private function getUnifiedDiffHunk( $lines = vec[]; foreach ($hunk as $op) { - if ($op is DiffKeepOp<_>) { + if ($op->isKeepOp()) { + $op = $op->asKeepOp(); $lines[] = ' '.$op->getContent(); $old_start ??= $op->getOldPos(); $new_start ??= $op->getNewPos(); @@ -110,7 +111,8 @@ private function getUnifiedDiffHunk( continue; } - if ($op is DiffDeleteOp<_>) { + if ($op->isDeleteOp()) { + $op = $op->asDeleteOp(); $lines[] = '-'.$op->getContent(); $old_start ??= $op->getOldPos(); $new_start ??= $op->getOldPos(); @@ -118,7 +120,8 @@ private function getUnifiedDiffHunk( continue; } - if ($op is DiffInsertOp<_>) { + if ($op->isInsertOp()) { + $op = $op->asInsertOp(); $lines[] = '+'.$op->getContent(); $old_start ??= $op->getNewPos(); $new_start ??= $op->getNewPos(); diff --git a/src/cluster.php b/src/cluster.php index 68236a1..893c44c 100644 --- a/src/cluster.php +++ b/src/cluster.php @@ -40,21 +40,22 @@ function cluster( $cluster ==> { $first = C\firstx($cluster); - if ($first is DiffDeleteOp<_>) { + if ($first->isDeleteOp()) { return new DiffDeleteOp( - $first->getOldPos(), + $first->asDeleteOp()->getOldPos(), Vec\map($cluster, $op ==> $op->asDeleteOp()->getContent()), ); } - if ($first is DiffInsertOp<_>) { + if ($first->isInsertOp()) { return new DiffInsertOp( - $first->getNewPos(), + $first->asInsertOp()->getNewPos(), Vec\map($cluster, $op ==> $op->asInsertOp()->getContent()), ); } - if ($first is DiffKeepOp<_>) { + if ($first->isKeepOp()) { + $first = $first->asKeepOp(); return new DiffKeepOp( $first->getOldPos(), $first->getNewPos(),