Added a slightly faster IndexOf method

This commit is contained in:
niksedk 2014-10-05 22:32:30 +02:00
parent 85d37dcf79
commit 5746892916
4 changed files with 48 additions and 9 deletions

View File

@ -34,5 +34,42 @@ namespace Nikse.SubtitleEdit.Core
{ {
return source.IndexOf(value, comparisonType) >= 0; return source.IndexOf(value, comparisonType) >= 0;
} }
// http://www.codeproject.com/Articles/43726/Optimizing-string-operations-in-C
public static int FastIndexOf(this string source, string pattern)
{
if (pattern == null) throw new ArgumentNullException();
if (pattern.Length == 0) return 0;
if (pattern.Length == 1) return source.IndexOf(pattern[0]);
int limit = source.Length - pattern.Length + 1;
if (limit < 1) return -1;
// Store the first 2 characters of "pattern"
char c0 = pattern[0];
char c1 = pattern[1];
// Find the first occurrence of the first character
int first = source.IndexOf(c0, 0, limit);
while (first != -1)
{
// Check if the following character is the same like
// the 2nd character of "pattern"
if (source[first + 1] != c1)
{
first = source.IndexOf(c0, ++first, limit - first);
continue;
}
// Check the rest of "pattern" (starting with the 3rd character)
bool found = true;
for (var j = 2; j < pattern.Length; j++)
if (source[first + j] != pattern[j])
{
found = false;
break;
}
// If the whole word was found, return its index, otherwise try again
if (found) return first;
first = source.IndexOf(c0, ++first, limit - first);
}
return -1;
}
} }
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -140,7 +141,7 @@ namespace Nikse.SubtitleEdit.Logic.Dictionaries
string newText = input; string newText = input;
string pre = string.Empty; string pre = string.Empty;
if (newText.StartsWith("<i>")) if (newText.StartsWith("<i>", StringComparison.Ordinal))
{ {
pre += "<i>"; pre += "<i>";
newText = newText.Remove(0, 3); newText = newText.Remove(0, 3);
@ -150,7 +151,7 @@ namespace Nikse.SubtitleEdit.Logic.Dictionaries
pre += newText[0]; pre += newText[0];
newText = newText.Substring(1); newText = newText.Substring(1);
} }
if (newText.StartsWith("<i>")) if (newText.StartsWith("<i>", StringComparison.Ordinal))
{ {
pre += "<i>"; pre += "<i>";
newText = newText.Remove(0, 3); newText = newText.Remove(0, 3);
@ -190,14 +191,15 @@ namespace Nikse.SubtitleEdit.Logic.Dictionaries
newText = pre + newText; newText = pre + newText;
string post = string.Empty; string post = string.Empty;
if (newText.EndsWith("</i>")) if (newText.EndsWith("</i>", StringComparison.Ordinal))
{ {
newText = newText.Remove(newText.Length - 4, 4); newText = newText.Remove(newText.Length - 4, 4);
post = "</i>"; post = "</i>";
} }
foreach (string from in _endLineReplaceList.Keys) foreach (string from in _endLineReplaceList.Keys)
{ {
if (newText.EndsWith(from)) if (newText.EndsWith(from, StringComparison.Ordinal))
{ {
int position = (newText.Length - from.Length); int position = (newText.Length - from.Length);
newText = newText.Remove(position).Insert(position, _endLineReplaceList[from]); newText = newText.Remove(position).Insert(position, _endLineReplaceList[from]);
@ -207,13 +209,13 @@ namespace Nikse.SubtitleEdit.Logic.Dictionaries
foreach (string from in PartialLineWordBoundaryReplaceList.Keys) foreach (string from in PartialLineWordBoundaryReplaceList.Keys)
{ {
if (newText.Contains(from)) if (newText.FastIndexOf(from) >= 0)
newText = ReplaceWord(newText, from, PartialLineWordBoundaryReplaceList[from]); newText = ReplaceWord(newText, from, PartialLineWordBoundaryReplaceList[from]);
} }
foreach (string from in _partialLineAlwaysReplaceList.Keys) foreach (string from in _partialLineAlwaysReplaceList.Keys)
{ {
if (newText.Contains(from)) if (newText.FastIndexOf(from) >= 0)
newText = newText.Replace(from, _partialLineAlwaysReplaceList[from]); newText = newText.Replace(from, _partialLineAlwaysReplaceList[from]);
} }
@ -251,7 +253,7 @@ namespace Nikse.SubtitleEdit.Logic.Dictionaries
int i = 0; int i = 0;
while (s.Contains(letter) && i < 10) while (s.Contains(letter) && i < 10)
{ {
int index = s.IndexOf(letter, StringComparison.Ordinal); int index = s.FastIndexOf(letter);
s = AddToGuessList(list, s, index, letter, _partialWordReplaceList[letter]); s = AddToGuessList(list, s, index, letter, _partialWordReplaceList[letter]);
AddToGuessList(list, word, index, letter, _partialWordReplaceList[letter]); AddToGuessList(list, word, index, letter, _partialWordReplaceList[letter]);
i++; i++;

View File

@ -968,7 +968,7 @@ namespace Nikse.SubtitleEdit.Logic.Ocr
foreach (string name in _namesEtcMultiWordList) foreach (string name in _namesEtcMultiWordList)
{ {
int start = tempLine.IndexOf(name, StringComparison.Ordinal); int start = tempLine.FastIndexOf(name);
if (start >= 0) if (start >= 0)
{ {
if (start == 0 || (Environment.NewLine + @" ¡¿,.!?:;()[]{}+-$£""”“#&%…—♪").Contains(tempLine[start - 1])) if (start == 0 || (Environment.NewLine + @" ¡¿,.!?:;()[]{}+-$£""”“#&%…—♪").Contains(tempLine[start - 1]))

View File

@ -128,7 +128,7 @@ namespace Nikse.SubtitleEdit.Logic
foreach (string name in namesEtc) foreach (string name in namesEtc)
{ {
int start = lower.IndexOf(name.ToLower(), StringComparison.Ordinal); int start = lower.FastIndexOf(name.ToLower());
while (start >= 0 && start < lower.Length) while (start >= 0 && start < lower.Length)
{ {
bool startOk = (start == 0) || (lower[start - 1] == ' ') || (lower[start - 1] == '-') || bool startOk = (start == 0) || (lower[start - 1] == ' ') || (lower[start - 1] == '-') ||