using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Occurrences
{
static class Program
{
static int useSubString(this string source, string pattern)
{
int count = 0;
int index;
while (true)
{
index = source.IndexOf(pattern);
if (index == -1)
return count;
source = source.Substring(index + pattern.Length);
count++;
}
}
static int useRemove(this string source, string pattern)
{
int count = 0;
int index;
while (true)
{
index = source.IndexOf(pattern);
if (index == -1)
return count;
source = source.Remove(index, pattern.Length);
count++;
}
}
static int useSplit(this string source, string pattern)
=> source.Split(new string[] { pattern }, StringSplitOptions.None).Count() - 1;
static int useRegexp(this string source, string pattern)
=> new Regex(pattern).Matches(source).Count;
static void sample()
{
var src = "тук - тук!";
var ptn = "тук";
$"'{ptn}' found on '{src}' use 'useSubString'\t {useSubString(src, ptn)} times...".print();
$"'{ptn}' found on '{src}' use 'useRemove'\t {useRemove(src, ptn)} times...".print();
$"'{ptn}' found on '{src}' use 'useSplit'\t {useSplit(src, ptn)} times...".print();
$"'{ptn}' found on '{src}' use 'useRegexp'\t {useRegexp(src, ptn)} times...".print();
}
static Random rnd = new Random();
static string pattren = genPattern();
static string genPattern()
{
var l = rnd.Next(10, 20);
var sb = new StringBuilder();
for (var i = 0; i < l; i++)
sb.Append((char)('A' + (char)rnd.Next(0, 26)));
return sb.ToString();
}
static List<string> sources = new List<string>();
static void fill(int n)
{
for (var i = 0; i < n; i++)
{
var l = rnd.Next(10, 20);
var sb = new StringBuilder();
for (var j = 0; j < l; j++)
if (rnd.Next(0, 7) % 3 != 0)
sb.Append((char)('A' + (char)rnd.Next(0, 26)));
else
sb.Append(pattren);
sources.Add(sb.ToString());
}
}
static void bench(int n, bool check = true)
{
// массивы что бы убрать влияние динамического создания объектов
var uss = new int[n];
var urm = new int[n];
var usp = new int[n];
var urx = new int[n];
var sw = new Stopwatch();
sw.Start();
fill(n);
var tsf = sw.Elapsed;
sw.Reset();
sw.Start();
for (var i = 0; i < n; i++)
uss[i] = sources[i].useSubString(pattren);
var tss = sw.Elapsed;
sw.Reset();
sw.Start();
for (var i = 0; i < n; i++)
urm[i] = sources[i].useRemove(pattren);
var trm = sw.Elapsed;
sw.Reset();
sw.Start();
for (var i = 0; i < n; i++)
usp[i] = sources[i].useSplit(pattren);
var tsp = sw.Elapsed;
sw.Reset();
sw.Start();
for (var i = 0; i < n; i++)
urx[i] = sources[i].useRegexp(pattren);
var trx = sw.Elapsed;
sw.Stop();
// весь вывод выносим за пределы замера
//Console.WriteLine(tsf.ToString(@"dddd\.hh\:mm\:ss\.fffffff"));
$"fill\t {tsf.ToString(@"hh\:mm\:ss\.fffff")}".print();
$"useSubString\t {tss.ToString(@"hh\:mm\:ss\.fffff")}".print();
$"useRemove\t {trm.ToString(@"hh\:mm\:ss\.fffff")}".print();
$"useSplit\t {tsp.ToString(@"hh\:mm\:ss\.fffff")}".print();
$"useRegexp\t {trx.ToString(@"hh\:mm\:ss\.fffff")}".print();
// выод размерности массивов, или чек, что бы сборщик мусора не успел возбудиться ))
if (check)
$"{chk(urm)} {chk(usp)} {chk(urx)}".print();
else
$"{uss.Length} {urm.Length} {usp.Length} {urx.Length}".print();
bool chk(int[] x)
{
for (var i = 0; i < x.Length; i++)
if (uss[i] != x[i])
return false;
return true;
}
}
static void Main(string[] args)
{
sample();
var n = 1_000_000;
bench(n);
}
static void print(this string s) => Console.WriteLine(s);
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Occurrences
{
static class Program
{
static int useSubString(this string source, string pattern)
{
int count = 0;
int index;
while (true)
{
index = source.IndexOf(pattern);
if (index == -1)
return count;
source = source.Substring(index + pattern.Length);
count++;
}
}
static int useRemove(this string source, string pattern)
{
int count = 0;
int index;
while (true)
{
index = source.IndexOf(pattern);
if (index == -1)
return count;
source = source.Remove(index, pattern.Length);
count++;
}
}
static int useSplit(this string source, string pattern)
=> source.Split(new string[] { pattern }, StringSplitOptions.None).Count() - 1;
static int useRegexp(this string source, string pattern)
=> new Regex(pattern).Matches(source).Count;
static void sample()
{
var src = "тук - тук!";
var ptn = "тук";
$"'{ptn}' found on '{src}' use 'useSubString'\t {useSubString(src, ptn)} times...".print();
$"'{ptn}' found on '{src}' use 'useRemove'\t {useRemove(src, ptn)} times...".print();
$"'{ptn}' found on '{src}' use 'useSplit'\t {useSplit(src, ptn)} times...".print();
$"'{ptn}' found on '{src}' use 'useRegexp'\t {useRegexp(src, ptn)} times...".print();
}
static Random rnd = new Random();
static string pattren = genPattern();
static string genPattern()
{
var l = rnd.Next(10, 20);
var sb = new StringBuilder();
for (var i = 0; i < l; i++)
sb.Append((char)('A' + (char)rnd.Next(0, 26)));
return sb.ToString();
}
static List<string> sources = new List<string>();
static void fill(int n)
{
for (var i = 0; i < n; i++)
{
var l = rnd.Next(10, 20);
var sb = new StringBuilder();
for (var j = 0; j < l; j++)
if (rnd.Next(0, 7) % 3 != 0)
sb.Append((char)('A' + (char)rnd.Next(0, 26)));
else
sb.Append(pattren);
sources.Add(sb.ToString());
}
}
static void bench(int n)
{
// массивы что бы убрать влияние динамического создания объектов
var uss = new int[n];
var urm = new int[n];
var usp = new int[n];
var urx = new int[n];
var sw = new Stopwatch();
sw.Start();
fill(n);
var tsf = sw.Elapsed;
sw.Reset();
sw.Start();
for (var i = 0; i < n; i++)
uss[i] = sources[i].useSubString(pattren);
var tss = sw.Elapsed;
sw.Reset();
sw.Start();
for (var i = 0; i < n; i++)
urm[i] = sources[i].useRemove(pattren);
var trm = sw.Elapsed;
sw.Reset();
sw.Start();
for (var i = 0; i < n; i++)
usp[i] = sources[i].useSplit(pattren);
var tsp = sw.Elapsed;
sw.Reset();
sw.Start();
for (var i = 0; i < n; i++)
urx[i] = sources[i].useRegexp(pattren);
var trx = sw.Elapsed;
sw.Stop();
// весь вывод выносим за пределы замера
$"fill\t {tsf.ToString(@"hh\:mm\:ss\.fffff")}".print();
$"useSubString\t {tss.ToString(@"hh\:mm\:ss\.fffff")}".print();
$"useRemove\t {trm.ToString(@"hh\:mm\:ss\.fffff")}".print();
$"useSplit\t {tsp.ToString(@"hh\:mm\:ss\.fffff")}".print();
$"useRegexp\t {trx.ToString(@"hh\:mm\:ss\.fffff")}".print();
// вывод размерности массивов, что бы сборщик мусора не успел возбудиться ))
$"{uss.Length} {urm.Length} {usp.Length} {urx.Length}".print();
}
static void Main(string[] args)
{
sample();
var n = 1_000_000;
bench(n);
}
static void print(this string s) => Console.WriteLine(s);
}
}
Кроме того вместо метода Remove можно использовать метод Substring. Здесь большой разницы в использовании между ними нет, то лично мне кажется что название Substring лучше отражает суть происходящего. Но тут уже дело вкуса.согласен что лучше отражает. мало того, это обычно приоритет в современном корпоративе - читаемость (а значит сопровождаемость кода)
while (true)
site:habr.com
это поиск по хабру )) .. (что собственно и гарантирует русскоязычность и качество материала).. кстати, синтаксис целевого указания поиска по сайту по ходу универсальный. именно в таком варианте, его точно поймут и гугл, и яндекс, и дак-дак, и многие другие (хотя мало кто еще чем то пользуется ;).. но далеко не все сайты, используют реально серьезные методы противодействия. возможно не обязательно пытаться охватить все сразу ))