C# 在这个小功能中,什么占据了大部分时间?很奇怪,并且给出了详细的分析
C# 在这个小功能中,什么占据了大部分时间?很奇怪,并且给出了详细的分析,c#,C#,blockProperty是dictionary bool块匹配(IList容器、字符串块、int-cut) { string[]blockArray=blockProperty[block]; int length=blockArray.length-cut; 如果(长度>容器计数) { 返回false; } for(int i=0;i
blockProperty
是dictionary
bool块匹配(IList容器、字符串块、int-cut)
{
string[]blockArray=blockProperty[block];
int length=blockArray.length-cut;
如果(长度>容器计数)
{
返回false;
}
for(int i=0;i
列为:包含已用时间、独占已用时间、包含百分比(整个程序)、独占百分比、呼叫数
如何根据分析细分优化方法?我觉得奇怪的是,方法(6042)的独占运行时间超过了包含时间(10095)的一半。试试看
if(!blockArray[length - 1 - i].Equals( container[container.Count - 1 - i]) )) {return false;}
为了进一步细分,您可以(出于测试目的)将函数拆分为小的“一行子函数”,这样您就可以看到剖析被进一步细分。另一个帮助是双击分析行,向您显示各个函数调用及其相对时间。按相反顺序遍历数组可能就是这样做的:据我所知,数组针对正向/顺序访问进行了优化。此外,您可能会阻止JIT使用所有这些算法进行边界检查消除。试试这个:
for (int i = cut; i < blockArray.Length; i++)
{
if (!StringComparer.Ordinal.Equals(blockArray[i], container[i]))
return false;
}
for(int i=cut;i
然而,最终这取决于数组中有多少项——如果有很多项,那么你就无能为力(除了使用不安全的代码,但这只会给你一点点额外的好处)
编辑:您可以使用hashcode提高负面案例的速度;以牺牲内存为代价
class StringAndHash
{
public int HashCode;
public string Value;
public StringAndHash(string value)
{
if (value == null)
HashCode = 0;
else
HashCode = StringComparer.Ordinal.GetHashCode(value.GetHashCode());
Value = value;
}
public static implicit operator string(StringAndHash value)
{
return value.Value;
}
public static implicit operator StringAndHash(string value)
{
return new StringAndHash(value);
}
public override int GetHashCode()
{
return HashCode;
}
public override bool Equals(object obj)
{
var sah = obj as StringAndHash;
if (!object.ReferenceEquals(sah, null))
{
return Equals(sah);
}
return base.Equals(obj);
}
public override bool Equals(StringAndHash obj)
{
return obj.HashCode == HashCode // This will improve perf in negative cases.
&& StringComparer.Ordinal.Equals(obj.Value, Value);
}
}
public Dictionary<string, StringAndHash[]> blockProperty;
bool BlockMatch(IList<StringAndHash> container, string block, int cut)
{
var blockArray = blockProperty[block];
var length = blockArray.Length - cut;
if (length > container.Count)
{
return false;
}
for (int i = cut; i < blockArray.Length; i++)
{
if (blockArray[i].Equals(container[i]))
{
return false;
}
}
return true;
}
类StringAndHash
{
公共整数哈希码;
公共字符串值;
publicstringandhash(字符串值)
{
如果(值==null)
HashCode=0;
其他的
HashCode=StringComparer.Ordinal.GetHashCode(value.GetHashCode());
价值=价值;
}
公共静态隐式运算符字符串(StringAndHash值)
{
返回值;
}
公共静态隐式运算符StringAndHash(字符串值)
{
返回新的StringAndHash(值);
}
公共覆盖int GetHashCode()
{
返回哈希码;
}
公共覆盖布尔等于(对象对象对象)
{
var sah=obj作为StringAndHash;
如果(!object.ReferenceEquals(sah,null))
{
返回等于(sah);
}
返回基数等于(obj);
}
公共覆盖布尔等于(StringAndHash obj)
{
return obj.HashCode==HashCode//这将在负面情况下提高性能。
&&StringComparer.Ordinal.Equals(对象值,值);
}
}
公共财产;
布尔块匹配(IList容器、字符串块、int-cut)
{
var blockArray=blockProperty[block];
变量长度=块数组。长度-切割;
如果(长度>容器计数)
{
返回false;
}
for(int i=cut;i
最初,我希望从string.enquality
所花费的时间将占方法总运行时间的80%。。。很显然,这里的结果仅仅是10%,你是否试图将“container.Count”从for循环中去掉?@deepee:我认为icollection.Count
是一个属性,而且速度很快(是icollection大小的O(1))。所以我不用费心去缓存它。虽然事件探查器记录了所有事件,总时间为1503,但我对此感到满意。@colinfang:这是别人回答的还是你自己回答的?我很高兴知道实际的原因…是等于快于!=?如果是这样,为什么?我不关心优化string.equality
,是神秘的6042引起了我的注意。如果你说.equals
确实有助于减少6042的开销,那么我将不胜感激。更快的是StringComparer.Ordinal.equals(a,b)
-序数比较是你能做的最快的字符串比较类型。数组不会被复制。Jonathan Dickinson:你说得对,也许我表达错了,我把它清理干净了。不过,他的问题是字典TValue
是string[]
,热点在这个方法中,他没有使用ToArray()
。哦,我忽略了那句话。在这种情况下,我删除了我答案的第一部分,只保留了细分建议,逐行讨论将在其他答案继续进行。
class StringAndHash
{
public int HashCode;
public string Value;
public StringAndHash(string value)
{
if (value == null)
HashCode = 0;
else
HashCode = StringComparer.Ordinal.GetHashCode(value.GetHashCode());
Value = value;
}
public static implicit operator string(StringAndHash value)
{
return value.Value;
}
public static implicit operator StringAndHash(string value)
{
return new StringAndHash(value);
}
public override int GetHashCode()
{
return HashCode;
}
public override bool Equals(object obj)
{
var sah = obj as StringAndHash;
if (!object.ReferenceEquals(sah, null))
{
return Equals(sah);
}
return base.Equals(obj);
}
public override bool Equals(StringAndHash obj)
{
return obj.HashCode == HashCode // This will improve perf in negative cases.
&& StringComparer.Ordinal.Equals(obj.Value, Value);
}
}
public Dictionary<string, StringAndHash[]> blockProperty;
bool BlockMatch(IList<StringAndHash> container, string block, int cut)
{
var blockArray = blockProperty[block];
var length = blockArray.Length - cut;
if (length > container.Count)
{
return false;
}
for (int i = cut; i < blockArray.Length; i++)
{
if (blockArray[i].Equals(container[i]))
{
return false;
}
}
return true;
}