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;
}