Метод Подстроки на строковом классе всегда чувствовал себя несоответствующим мне. Обычно, когда Вы делаете подстроку, Вы знаете символ (символы) от того, где Вы хотите запуститься, и charachter (s), где Вы хотите закончиться. Таким образом я всегда чувствовал, что должны определить длину, поскольку второй параметр глуп. Поэтому я записал свои собственные дополнительные методы. Тот, который берет startIndex и endIndex. И один, который берет startText (строка) и endText (строка), таким образом, можно просто определить текст от того, где запустить подстроку и текст для того, где закончить его.
ПРИМЕЧАНИЕ: Я не мог назвать Подстроку метода как в.NET, потому что моя первая перегрузка берет те же типы параметра в качестве одной из перегрузок.NET. Поэтому я назвал их Subsetstring. Не стесняйтесь добавлять к CodePlex...
public static class StringExtensions
{
/// <summary>
/// Returns a Subset string starting at the specified start index and ending and the specified end
/// index.
/// </summary>
/// <param name="s">The string to retrieve the subset from.</param>
/// <param name="startIndex">The specified start index for the subset.</param>
/// <param name="endIndex">The specified end index for the subset.</param>
/// <returns>A Subset string starting at the specified start index and ending and the specified end
/// index.</returns>
public static string Subsetstring(this string s, int startIndex, int endIndex)
{
if (startIndex > endIndex)
{
throw new InvalidOperationException("End Index must be after Start Index.");
}
if (startIndex < 0)
{
throw new InvalidOperationException("Start Index must be a positive number.");
}
if(endIndex <0)
{
throw new InvalidOperationException("End Index must be a positive number.");
}
return s.Substring(startIndex, (endIndex - startIndex));
}
/// <summary>
/// Finds the specified Start Text and the End Text in this string instance, and returns a string
/// containing all the text starting from startText, to the begining of endText. (endText is not
/// included.)
/// </summary>
/// <param name="s">The string to retrieve the subset from.</param>
/// <param name="startText">The Start Text to begin the Subset from.</param>
/// <param name="endText">The End Text to where the Subset goes to.</param>
/// <param name="ignoreCase">Whether or not to ignore case when comparing startText/endText to the string.</param>
/// <returns>A string containing all the text starting from startText, to the begining of endText.</returns>
public static string Subsetstring(this string s, string startText, string endText, bool ignoreCase)
{
if (string.IsNullOrEmpty(startText) || string.IsNullOrEmpty(endText))
{
throw new ArgumentException("Start Text and End Text cannot be empty.");
}
string temp = s;
if (ignoreCase)
{
temp = s.ToUpperInvariant();
startText = startText.ToUpperInvariant();
endText = endText.ToUpperInvariant();
}
int start = temp.IndexOf(startText);
int end = temp.IndexOf(endText, start);
return Subsetstring(s, start, end);
}
}
Использование:
string s = "This is a tester for my cool extension method!!";
s = s.Subsetstring("tester", "cool",true);
Вывод: "тестер для мой"
Помещение всех тестов в одну и ту же программу является ошибкой микробенчмаркинга - есть определенная разминка, связанная с производительностью Java. Это самая важная ошибка.
Поместите ваши тесты в отдельные программы. Затем запустите тесты несколько раз, чтобы вы почувствовали, когда закончилась разминка и статистическая значимость.
Также у вас есть огромный метод, содержащий ваш внутренний цикл. Hotspot, похоже, справляется с этим лучше, чем раньше, но это все еще не очень хорошо.
Вы должны обнаружить это с -сервером
, вызывающим виртуальный метод (даже если он загружен другим загрузчик классов) в замкнутом цикле полностью оптимизируется. Поэтому нет смысла говорить, насколько прямой вызов быстрее, чем рефлексивный.
Во-первых, отражение стало намного быстрее в самых последних JDK. Во-вторых, я ожидаю, что компилятор Hot Spot оптимизирует все эти вызовы примерно до кода. Он может выполнять анализ времени выполнения, чтобы понять, что вы вызываете одну и ту же функцию снова и снова, чтобы оптимизировать отражение (и вызов виртуальной функции). То же самое и с примером интерфейса.