[llvm] 638b0fb - [ADT][NFC] Early bail out for ComputeEditDistance

Nathan James via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 8 00:20:36 PDT 2022


Author: Nathan James
Date: 2022-06-08T08:20:29+01:00
New Revision: 638b0fb4d6517cb6517df88eeae2d0210d021040

URL: https://github.com/llvm/llvm-project/commit/638b0fb4d6517cb6517df88eeae2d0210d021040
DIFF: https://github.com/llvm/llvm-project/commit/638b0fb4d6517cb6517df88eeae2d0210d021040.diff

LOG: [ADT][NFC] Early bail out for ComputeEditDistance

The minimun bound for number of edits is the size difference between the 2 arrays.
If MaxEditDistance is smaller than this, we can bail out early without needing to traverse any of the arrays.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D127070

Added: 
    llvm/unittests/ADT/EditDistanceTest.cpp

Modified: 
    llvm/include/llvm/ADT/edit_distance.h
    llvm/unittests/ADT/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/edit_distance.h b/llvm/include/llvm/ADT/edit_distance.h
index 6989cecab9b13..6df3db6125d40 100644
--- a/llvm/include/llvm/ADT/edit_distance.h
+++ b/llvm/include/llvm/ADT/edit_distance.h
@@ -61,6 +61,15 @@ unsigned ComputeMappedEditDistance(ArrayRef<T> FromArray, ArrayRef<T> ToArray,
   typename ArrayRef<T>::size_type m = FromArray.size();
   typename ArrayRef<T>::size_type n = ToArray.size();
 
+  if (MaxEditDistance) {
+    // If the 
diff erence in size between the 2 arrays is larger than the max
+    // distance allowed, we can bail out as we will always need at least
+    // MaxEditDistance insertions or removals.
+    typename ArrayRef<T>::size_type AbsDiff = m > n ? m - n : n - m;
+    if (AbsDiff > MaxEditDistance)
+      return MaxEditDistance + 1;
+  }
+
   const unsigned SmallBufferSize = 64;
   unsigned SmallBuffer[SmallBufferSize];
   std::unique_ptr<unsigned[]> Allocated;

diff  --git a/llvm/unittests/ADT/CMakeLists.txt b/llvm/unittests/ADT/CMakeLists.txt
index 3b3d7c5483c20..c6bd570d69ae7 100644
--- a/llvm/unittests/ADT/CMakeLists.txt
+++ b/llvm/unittests/ADT/CMakeLists.txt
@@ -22,6 +22,7 @@ add_llvm_unittest(ADTTests
   DenseSetTest.cpp
   DepthFirstIteratorTest.cpp
   DirectedGraphTest.cpp
+  EditDistanceTest.cpp
   EnumeratedArrayTest.cpp
   EquivalenceClassesTest.cpp
   FallibleIteratorTest.cpp

diff  --git a/llvm/unittests/ADT/EditDistanceTest.cpp b/llvm/unittests/ADT/EditDistanceTest.cpp
new file mode 100644
index 0000000000000..6e35f1b56ceb6
--- /dev/null
+++ b/llvm/unittests/ADT/EditDistanceTest.cpp
@@ -0,0 +1,63 @@
+//===- llvm/unittest/Support/EditDistanceTest.cpp - Edit distance tests ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/edit_distance.h"
+#include "gtest/gtest.h"
+#include <cstdlib>
+
+using namespace llvm;
+
+namespace {
+
+struct Result {
+  unsigned NumMaps;
+  unsigned EditDist;
+};
+} // namespace
+
+static Result editDistanceAndMaps(StringRef A, StringRef B,
+                                  unsigned MaxEditDistance = 0) {
+  unsigned NumMaps = 0;
+  auto TrackMaps = [&](const char X) {
+    ++NumMaps;
+    return X;
+  };
+  unsigned EditDist = llvm::ComputeMappedEditDistance(
+      makeArrayRef(A.data(), A.size()), makeArrayRef(B.data(), B.size()),
+      TrackMaps, true, MaxEditDistance);
+  return {NumMaps, EditDist};
+}
+
+TEST(EditDistance, VerifyShortCircuit) {
+  StringRef Hello = "Hello";
+  StringRef HelloWorld = "HelloWorld";
+  Result R = editDistanceAndMaps(Hello, HelloWorld, 5);
+  EXPECT_EQ(R.EditDist, 5U);
+  EXPECT_GT(R.NumMaps, 0U);
+
+  R = editDistanceAndMaps(Hello, HelloWorld);
+  EXPECT_EQ(R.EditDist, 5U);
+  EXPECT_GT(R.NumMaps, 0U);
+
+  R = editDistanceAndMaps(Hello, HelloWorld, 4);
+  EXPECT_EQ(R.EditDist, 5U);
+  EXPECT_EQ(R.NumMaps, 0U);
+
+  R = editDistanceAndMaps(HelloWorld, Hello, 4);
+  EXPECT_EQ(R.EditDist, 5U);
+  EXPECT_EQ(R.NumMaps, 0U);
+
+  R = editDistanceAndMaps(Hello, HelloWorld, 1);
+  EXPECT_EQ(R.EditDist, 2U);
+  EXPECT_EQ(R.NumMaps, 0U);
+
+  R = editDistanceAndMaps(HelloWorld, Hello, 1);
+  EXPECT_EQ(R.EditDist, 2U);
+  EXPECT_EQ(R.NumMaps, 0U);
+}


        


More information about the llvm-commits mailing list