并行比普通的 foreach 花费更多的时间
Parallelism takes much more time than a regular foreach
我想通过添加并行功能来改进我的凯撒密码,但对代码的进一步测量表明,并行方法比正常方法需要更多的时间才能完成。
为什么?
正常
public string CaesarEncrypt(string text, int positions, char[] charSet = null) {
if (string.IsNullOrEmpty(charSet)) {
charSet = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789").ToCharArray();
}
List<char> charList = charSet.ToList();
StringBuilder sb = new StringBuilder { Capacity = text.Length };
foreach (char c in text) {
int charPos = charList.IndexOf(c);
if ((charPos == -1)) {
sb.Append(c);
} else {
while (!(((charPos + positions) < (charSet.Length)))) {
charPos -= charSet.Length;
}
sb.Append(charSet(charPos + positions));
}
}
return sb.ToString();
}
平行
public string CaesarEncrypt(string text, int positions, char[] charSet = null) {
if (string.IsNullOrEmpty(charSet)) {
charSet = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789").ToCharArray();
}
List<char> charList = charSet.ToList();
StringBuilder sb = new StringBuilder { Capacity = text.Length };
Parallel.ForEach(text.ToArray(), (char c) =>
{
int charPos = charList.IndexOf(c);
if ((charPos == -1)) {
sb.Append(c);
} else {
while (!(((charPos + positions) < (charSet.Length)))) {
charPos -= charSet.Length;
}
sb.Append(charSet(charPos + positions));
}
});
return sb.ToString();
}
多线程的管理有一定的成本。如果循环体内的任务太小,这个开销可能会大于多线程的增益。
这里的另一个问题是你在平行体中附加了一个StringBuilder
。由于无法保证线程将以何种顺序完成,因此最后可能会得到混乱的结果。
我想通过添加并行功能来改进我的凯撒密码,但对代码的进一步测量表明,并行方法比正常方法需要更多的时间才能完成。
为什么?
正常
public string CaesarEncrypt(string text, int positions, char[] charSet = null) {
if (string.IsNullOrEmpty(charSet)) {
charSet = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789").ToCharArray();
}
List<char> charList = charSet.ToList();
StringBuilder sb = new StringBuilder { Capacity = text.Length };
foreach (char c in text) {
int charPos = charList.IndexOf(c);
if ((charPos == -1)) {
sb.Append(c);
} else {
while (!(((charPos + positions) < (charSet.Length)))) {
charPos -= charSet.Length;
}
sb.Append(charSet(charPos + positions));
}
}
return sb.ToString();
}
平行
public string CaesarEncrypt(string text, int positions, char[] charSet = null) {
if (string.IsNullOrEmpty(charSet)) {
charSet = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789").ToCharArray();
}
List<char> charList = charSet.ToList();
StringBuilder sb = new StringBuilder { Capacity = text.Length };
Parallel.ForEach(text.ToArray(), (char c) =>
{
int charPos = charList.IndexOf(c);
if ((charPos == -1)) {
sb.Append(c);
} else {
while (!(((charPos + positions) < (charSet.Length)))) {
charPos -= charSet.Length;
}
sb.Append(charSet(charPos + positions));
}
});
return sb.ToString();
}
多线程的管理有一定的成本。如果循环体内的任务太小,这个开销可能会大于多线程的增益。
这里的另一个问题是你在平行体中附加了一个StringBuilder
。由于无法保证线程将以何种顺序完成,因此最后可能会得到混乱的结果。