问题描述
||
看看这个片段:
public class StringToggler
{
static readonly bool[] ToggleableLatinChars = new[]
{
// 256 bools here
};
readonly bool[] LocalToggleableLatinChars = ToggleableLatinChars;
public string Toggle(string s)
{
// blah blah
if (LocalToggleableLatinChars[(byte) ch])
{
// blah blah
}
// blah blah
}
// blah blah
}
与我直接使用ToggleableLatinChars相比,此代码可证明在测试中更快(7%ish)。
(在该方法中,使用本地引用ToggleableLatinChars的速度也相同)。
仅当针对.NET 4进行编译时,才会注意到这种效果。
当为.NET 3.5编译时,我看到相反的效果-使用静态数组明显更快。 (我的机器是运行Windows 7 64位的Intel i5,并且正在针对x86进行编译)
知道为什么吗?
更新:
这是一个完整的代码示例,与Marc的测试示例更相似。注意我现在正在使用静态和局部变量版本(不再是成员变量)。尽管我看到的差异少于我最初的测试代码所看到的差异,但是为.NET 4编译时,本地版本总是更快。您可以交换运行顺序,但是Local总是对我有利。 (针对.NET 3.5进行的编译不会这样做:它比.NET 4的运行速度要快得多,而静态的速度要快得多或相同)
using System;
using System.Diagnostics;
using System.Globalization;
internal class Program
{
const int RepeatCount = 500000;
const string TestString1_Unicode = @\"?=3.1415926?!! ?a??!#!%# ÜBERGRößEN!!?????? ??????@!e=2.71828182?#!!$@\\^i^/!@$\";
const string TestString2_Numbers = @\"p=3.14159265358979323846264338327950288419716939937510....!!!!\";
const string TestString3_LowerCase = @\"nevr un-den-erstimate ze pauer of stoopid piplz in larg grupp!\\*^*/\";
const string TestString4_UpperCase = @\"DUDE,WHY U R HERE?? U SHOULDA BE IN THE MEETING (BLAH-BLAH) $\\*o*/$!\";
static void Main()
{
RunTestsStaticAccess();
RunTestsLocalAccess();
Console.ReadLine();
}
public static void RunTestsLocalAccess()
{
StringToggler st = new StringToggler();
var watch = Stopwatch.StartNew();
for (int i = 0; i < RepeatCount; i++)
{
st.ToggleCase_LocalAccess(TestString1_Unicode);
st.ToggleCase_LocalAccess(TestString2_Numbers);
st.ToggleCase_LocalAccess(TestString3_LowerCase);
st.ToggleCase_LocalAccess(TestString4_UpperCase);
}
watch.Stop();
Console.WriteLine(\"{0}: {1}ms\",\"RunTestsLocalAccess\",watch.ElapsedMilliseconds);
}
public static void RunTestsStaticAccess()
{
StringToggler st = new StringToggler();
var watch = Stopwatch.StartNew();
for (int i = 0; i < RepeatCount; i++)
{
st.ToggleCase_StaticAccess(TestString1_Unicode);
st.ToggleCase_StaticAccess(TestString2_Numbers);
st.ToggleCase_StaticAccess(TestString3_LowerCase);
st.ToggleCase_StaticAccess(TestString4_UpperCase);
}
watch.Stop();
Console.WriteLine(\"{0}: {1}ms\",\"RunTestsStaticAccess\",watch.ElapsedMilliseconds);
}
public class StringToggler
{
static readonly bool[] ToggleableLatinChars = new[]
{
false,false,true,false
};
readonly TextInfo textInfo;
public StringToggler()
{
textInfo = CultureInfo.CurrentCulture.TextInfo;
}
public StringToggler(CultureInfo cultureInfo)
{
textInfo = cultureInfo.TextInfo;
}
public unsafe string ToggleCase_StaticAccess(string s)
{
s = string.Copy(s);
fixed(char* p = s)
{
for (int i = 0; i < s.Length; i++)
{
char ch = p[i];
if (ch <= 0xff)
{
if (ToggleableLatinChars[(byte) ch])
{
p[i] = (char) (ch ^ 0x20);
}
}
else
{
switch (CharUnicodeInfo.GetUnicodeCategory(ch))
{
case UnicodeCategory.UppercaseLetter:
p[i] = textInfo.ToLower(ch);
break;
case UnicodeCategory.LowercaseLetter:
p[i] = textInfo.ToUpper(ch);
break;
}
}
}
}
return s;
}
public unsafe string ToggleCase_LocalAccess(string s)
{
s = string.Copy(s);
var toggleableLatinChars = ToggleableLatinChars;
fixed(char* p = s)
{
for (int i = 0; i < s.Length; i++)
{
char ch = p[i];
if (ch <= 0xff)
{
if (toggleableLatinChars[(byte) ch])
{
p[i] = (char) (ch ^ 0x20);
}
}
else
{
switch (CharUnicodeInfo.GetUnicodeCategory(ch))
{
case UnicodeCategory.UppercaseLetter:
p[i] = textInfo.ToLower(ch);
break;
case UnicodeCategory.LowercaseLetter:
p[i] = textInfo.ToUpper(ch);
break;
}
}
}
}
return s;
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)