Optimize "GetCharactersPerSecond"

This commit is contained in:
Nikolaj Olsson 2018-01-23 11:12:58 +01:00
parent f7ffc1deb0
commit 2153641aaf
3 changed files with 72 additions and 17 deletions

View File

@ -329,21 +329,45 @@ namespace Nikse.SubtitleEdit.Core
return new string(array, 0, arrayIndex);
}
public static string RemoveWhiteSpaces(this string value, bool removeNormalSpace)
/// <summary>
/// Count characters excl. white spaces/ssa-tags/html-tags and normal space depending on parameter.
/// </summary>
public static int CountCharacters(this string value, bool removeNormalSpace)
{
int length = 0;
const char zeroWidthSpace = '\u200B';
const char zeroWidthNoBreakSpace = '\uFEFF';
char normalSpace = removeNormalSpace ? ' ' : zeroWidthSpace;
bool ssaTagOn = false;
bool htmlTagOn = false;
char[] array = new char[value.Length];
int arrayIndex = 0;
for (int i = 0; i < value.Length; i++)
{
char ch = value[i];
if (ch != '\n' && ch != '\r' && ch != '\t' && ch != zeroWidthSpace && ch != zeroWidthNoBreakSpace && ch != normalSpace)
array[arrayIndex++] = ch;
if (ssaTagOn)
{
if (ch == '}')
ssaTagOn = false;
}
else if (htmlTagOn)
{
if (ch == '>')
htmlTagOn = false;
}
else if (ch == '{' && i < value.Length - 1 && value[i + 1] == '\\')
{
ssaTagOn = true;
}
else if (ch == '<' && i < value.Length - 1 && (value[i + 1] == '/' || char.IsLetter(value[i + 1])) && value.IndexOf('>', i) > 0)
{
htmlTagOn = true;
}
else if (ch != '\n' && ch != '\r' && ch != '\t' && ch != zeroWidthSpace && ch != zeroWidthNoBreakSpace && ch != normalSpace)
{
length++;
}
}
return new string(array, 0, arrayIndex);
return length;
}
}

View File

@ -841,8 +841,7 @@ namespace Nikse.SubtitleEdit.Core
if (paragraph.Duration.TotalMilliseconds < 1)
return 999;
string s = HtmlUtil.RemoveHtmlTags(paragraph.Text, true).RemoveWhiteSpaces(Configuration.Settings.General.CharactersPerSecondsIgnoreWhiteSpace);
return s.Length / paragraph.Duration.TotalSeconds;
return paragraph.Text.CountCharacters(Configuration.Settings.General.CharactersPerSecondsIgnoreWhiteSpace) / paragraph.Duration.TotalSeconds;
}
public static bool IsRunningOnMono()

View File

@ -184,27 +184,59 @@ namespace Test.Core
}
[TestMethod]
public void RemoveWhiteSpaces1()
public void CountLetters1()
{
string input = " Hallo world! ";
var res = input.RemoveWhiteSpaces(false);
Assert.AreEqual(input, res);
var res = input.CountCharacters(false);
Assert.AreEqual(" Hallo world! ".Length, res);
}
[TestMethod]
public void RemoveWhiteSpaces2()
public void CountLetters2()
{
string input = " Hallo " + Environment.NewLine + " world! ";
var res = input.RemoveWhiteSpaces(true);
Assert.AreEqual("Halloworld!", res);
var res = input.CountCharacters(true);
Assert.AreEqual("Halloworld!".Length, res);
}
[TestMethod]
public void RemoveWhiteSpaces3()
public void CountLetters3()
{
string input = " Hallo" + Environment.NewLine + "world!";
var res = input.RemoveWhiteSpaces(false);
Assert.AreEqual(" Halloworld!", res);
var res = input.CountCharacters(false);
Assert.AreEqual(" Halloworld!".Length, res);
}
[TestMethod]
public void CountLetters4Ssa()
{
string input = "{\\an1}Hallo";
var res = input.CountCharacters(true);
Assert.AreEqual("Hallo".Length, res);
}
[TestMethod]
public void CountLetters4Html()
{
string input = "<i>Hallo</i>";
var res = input.CountCharacters(true);
Assert.AreEqual("Hallo".Length, res);
}
[TestMethod]
public void CountLetters5HtmlFont()
{
string input = "<font color=\"red\"><i>Hal lo<i></font>";
var res = input.CountCharacters(true);
Assert.AreEqual("Hallo".Length, res);
}
[TestMethod]
public void CountLetters6HtmlFontMultiLine()
{
string input = "<font color=\"red\"><i>Hal lo<i></font>" + Environment.NewLine + "<i>Bye!</i>";
var res = input.CountCharacters(true);
Assert.AreEqual("HalloBye!".Length, res);
}
}