[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