[英]How can I speed up indexof in c#?
Here are two strings:这里有两个字符串:
string a="abcdefghijklmnopqrstuvwxyz";
string A="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
The strings have 1500 characters and each character in the string is unique and constant.字符串有 1500 个字符,字符串中的每个字符都是唯一且恒定的。
When there is an article, I have to get the index in a
of each character in it.当有一篇文章时,我必须获取其中每个字符
a
索引。 And then return the corresponding index of the character in A
.然后返回
A
中字符的对应索引。
For example:例如:
If the article is "Here is an article", it will return "HERE IS AN ARTICLE".如果文章是“这是一篇文章”,它将返回“这是一篇文章”。
What I want to do is not just character uppercase.我想做的不仅仅是字符大写。 I am not allowed to show the source code, so I can only show an example that is alike to my project.
我不允许展示源代码,所以我只能展示一个与我的项目相似的例子。 Please excuse this.
请原谅。
The List way:列表方式:
public string Translate(string i)
{
DateTime DT = DateTime.Now;
StringBuilder SB = new StringBuilder();
foreach (char c in i)
{
int j = a.IndexOf(c);
if (j != -1)
{
SB.Append(A[j]);
}
else
{
SB.Append(c.ToString());
}
}
Debug.WriteLine("Time:" + (DateTime.Now - DT).TotalMilliseconds + "ms");
return SB.ToString();
}
I tried to use an article that is 4000 characters in length to test it.我尝试使用一篇 4000 个字符的文章来测试它。 It spends 400ms to finish it.
它花费了 400 毫秒来完成它。
I want to speed this up.我想加快速度。 I considered
Dictionary
or List
may be faster, so I modified the code like this:我认为
Dictionary
或List
可能会更快,所以我修改了如下代码:
The Dictionary way:字典方式:
public static List<T> d = new List<T>();
public class T
{
public string s;
public string t;
}
public static string Translate(string i)
{
if (d.Count == 0)
{
foreach (char c in a)
{
int o = a.IndexOf(c);
d.Add(new T() { s = c.ToString(), t = A[o].ToString() });
}
}
DateTime DT = DateTime.Now;
StringBuilder SB = new StringBuilder();
foreach (char c in i)
{
var Elements = d.Where(X => X.s == c.ToString());
if (Elements.Count() == 0)
{
SB.Append(c.ToString());
}
else
{
SB.Append(Elements.FirstOrDefault().t);
}
}
Debug.WriteLine("Time:" + (DateTime.Now - DT).TotalMilliseconds + "ms");
return SB.ToString();
}
Finally, it spends about 20s to finish it, much more than using the IndexOf
method.最后,它花费了大约 20 秒来完成它,比使用
IndexOf
方法要多得多。 I tried the Dictionary
way after that and found it wastes much more time than List
.之后我尝试了
Dictionary
方式,发现它比List
浪费更多时间。 Obviously Dictionary
and List
is not the right way.显然
Dictionary
和List
不是正确的方法。
I wonder if there is any way for me to make it faster?我想知道有什么方法可以让我更快吗? Thank you.
谢谢你。
I would try using Dictionary<char, char>
for mapping and using char array and string
ctor accepting one instead of StringBuilder
:我会尝试使用
Dictionary<char, char>
进行映射并使用 char 数组和string
ctor 接受一个而不是StringBuilder
:
static string A = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static Dictionary<char, char> Mapped = "abcdefghijklmnopqrstuvwxyz".Select((c, i) => (c, As: A[i])).ToDictionary(x => x.c, x => x.As);
public static string Translate(string s)
{
DateTime DT = DateTime.Now;
var res = new char[s.Length];
for (int i = 0; i < s.Length; i++)
{
var c = s[i];
if(Mapped.ContainsKey(c))
{
res[i] = Mapped[c];
}
else
{
res[i] = c;
}
}
Debug.WriteLine("Time:" + (DateTime.Now - DT).TotalMilliseconds + "ms");
return new string(res);
}
Also to benchmark this kind of code personally I prefer to use BenchmarkDotNet .另外,为了亲自对此类代码进行基准测试,我更喜欢使用BenchmarkDotNet 。
How about putting the string a
into a dictionary with the character as the key and the mapped value from A
as the value.如何将字符串
a
放入字典中,以字符作为键,将A
中的映射值作为值。
void Main()
{
Translate("Hej").Dump();
}
const string A = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static Dictionary<char, char> a = "abcdefghijklmnopqrstuvwxyz"
.Select((c, i) => (c, i))
.ToDictionary(x => x.c, x => A[x.i]);
public string Translate(string i)
{
DateTime DT = DateTime.Now;
StringBuilder SB = new StringBuilder(i.Length);
foreach (char c in i)
{
if (a.TryGetValue(c, out var r))
{
SB.Append(r);
}
else
{
SB.Append(c.ToString());
}
}
Debug.WriteLine("Time:" + (DateTime.Now - DT).TotalMilliseconds + "ms");
return SB.ToString();
}
If you want speed and string a
and A
have the same length... Then this might be what you want.如果您希望速度和字符串
a
和A
具有相同的长度......那么这可能就是您想要的。
private static string a = "abcdefghijklmnopqrstuvwxyz";
private static string A = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static unsafe void MakeWeirdStuff(string value)
{
if (value == null || value.Length == 0)
{
return;
}
fixed (char* chr = value)
{
for (int i = 0; i < value.Length; i++)
{
char valueChar = *(chr + i);
int index = a.IndexOf(valueChar);
if (index >= 0)
*(chr + i) = A[index];
}
}
}
Don't forget to allow unsafe code in your project and compile it in "Release" mode with optimization turned on.不要忘记在您的项目中允许不安全代码并在“发布”模式下编译它并打开优化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.