Skip to content

Commit a20dd1f

Browse files
committed
avoid second iteration when checking equality and common prefix
1 parent 17d5fee commit a20dd1f

File tree

1 file changed

+19
-21
lines changed

1 file changed

+19
-21
lines changed

DiffMatchPatch.zig

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,9 @@ fn diffInternal(
127127
check_lines: bool,
128128
deadline: u64,
129129
) DiffError!DiffList {
130-
// Check for equality (speedup).
131-
if (std.mem.eql(u8, before, after)) {
130+
// Trim off common prefix (speedup).
131+
const common_prefix_length = std.mem.indexOfDiff(u8, before, after) orelse {
132+
// equality
132133
var diffs: DiffList = .empty;
133134
errdefer deinitDiffList(allocator, &diffs);
134135
if (before.len != 0) {
@@ -139,19 +140,17 @@ fn diffInternal(
139140
});
140141
}
141142
return diffs;
142-
}
143+
};
143144

144-
// Trim off common prefix (speedup).
145-
var common_length = diffCommonPrefix(before, after);
146-
const common_prefix = before[0..common_length];
147-
var trimmed_before = before[common_length..];
148-
var trimmed_after = after[common_length..];
145+
const common_prefix = before[0..common_prefix_length];
146+
var trimmed_before = before[common_prefix_length..];
147+
var trimmed_after = after[common_prefix_length..];
149148

150149
// Trim off common suffix (speedup).
151-
common_length = diffCommonSuffix(trimmed_before, trimmed_after);
152-
const common_suffix = trimmed_before[trimmed_before.len - common_length ..];
153-
trimmed_before = trimmed_before[0 .. trimmed_before.len - common_length];
154-
trimmed_after = trimmed_after[0 .. trimmed_after.len - common_length];
150+
const common_suffix_length = diffCommonSuffix(trimmed_before, trimmed_after);
151+
const common_suffix = trimmed_before[trimmed_before.len - common_suffix_length ..];
152+
trimmed_before = trimmed_before[0 .. trimmed_before.len - common_suffix_length];
153+
trimmed_after = trimmed_after[0 .. trimmed_after.len - common_suffix_length];
155154

156155
// Compute the diff on the middle block.
157156
var diffs = try dmp.diffCompute(allocator, trimmed_before, trimmed_after, check_lines, deadline);
@@ -178,17 +177,16 @@ fn diffInternal(
178177
return diffs;
179178
}
180179

181-
fn diffCommonPrefix(before: []const u8, after: []const u8) usize {
182-
const n = @min(before.len, after.len);
183-
var i: usize = 0;
184-
185-
while (i < n) : (i += 1) {
186-
if (before[i] != after[i]) {
187-
return i;
188-
}
180+
fn indexOfDiff(comptime T: type, a: []const T, b: []const T) ?usize {
181+
const shortest = @min(a.len, b.len);
182+
for (a[0..shortest], b[0..shortest], 0..) |a_char, b_char, index| {
183+
if (a_char != b_char) return index;
189184
}
185+
return if (a.len == b.len) null else shortest;
186+
}
190187

191-
return n;
188+
fn diffCommonPrefix(before: []const u8, after: []const u8) usize {
189+
return indexOfDiff(u8, before, after) orelse @min(before.len, after.len);
192190
}
193191

194192
fn diffCommonSuffix(before: []const u8, after: []const u8) usize {

0 commit comments

Comments
 (0)