Performance 一种基于比较的算法性能分析

Performance 一种基于比较的算法性能分析,performance,algorithm,Performance,Algorithm,我有一个用Java编写的算法,在这个算法中,我需要确保函数调用不会重复,如果已经进行了。让我解释一下逻辑: 有一组可用的函数:函数1、函数2、…、函数n及其参数 使用一组值作为参数进行函数1调用,并生成一个结果 函数1调用、作为参数传递的值以及生成的结果都存储在内存中 当进行函数2调用时,函数2调用、作为参数传递的值和结果存储在内存中 当再次调用函数1时,使用不同的值作为参数,新调用(即它的值和结果)存储在内存中 现在,当再次进行函数1调用时,使用与上面2中的参数相同的值,因为之前进行了完全相同

我有一个用Java编写的算法,在这个算法中,我需要确保函数调用不会重复,如果已经进行了。让我解释一下逻辑:

  • 有一组可用的函数:函数1、函数2、…、函数n及其参数

  • 使用一组值作为参数进行函数1调用,并生成一个结果

  • 函数1调用、作为参数传递的值以及生成的结果都存储在内存中

  • 当进行函数2调用时,函数2调用、作为参数传递的值和结果存储在内存中

  • 当再次调用函数1时,使用不同的值作为参数,新调用(即它的值和结果)存储在内存中

  • 现在,当再次进行函数1调用时,使用与上面2中的参数相同的值,因为之前进行了完全相同的调用,我们不想再次执行函数调用,但我们需要检索存储在上面2中的结果

  • 我们当前的策略是将函数调用、它们的值和结果存储在映射中。对于每个新的函数调用,我们首先查看映射图中是否已经调用了该函数。如果是这样,我们将逐个比较函数调用中传递的值与存储在内存中的先前函数调用的值

    随着函数调用数量的增加,我们会遇到一些性能问题。对于每个新调用,我们将每个值与内存中存储的值进行比较。 因此,当我们每次调用100000次函数1时,使用不同的值,我再次调用函数1,使用以前从未使用过的值A、B、C,我需要将100000次A、B和C与之前100000次函数调用的存储值进行比较。然后还有一个电话,我又比较了100001次


    性能恶化到非常非常慢的程度。关于如何改进该算法,您有什么建议吗?

    您不应该只将函数的类型存储为映射的键,而应该存储包含所有参数的整个调用。因此,有必要编写一个FunctionCall类作为键。可能是这样的:

    enum Funtions{Funktion1, Funktion2, Funktion3};
    
    class FunctionKey(){
        public Functions function;
        public int value1
        public int value2
    
        public int hashCode(){
            int result = 1 + function.ordinal();
            result = result * 31 + value1;
            result = result * 17 + value2;
            return result;
        }
    
        public boolean equals(Object obj){
            if (!(obj instanceof FunctionKey))
                  return false;
            FunctionKey that = (FunctionKey) obj;
            return function == that.function && value1 == that.value1 && value2 == that.value2;
        }
    }
    
    Map<FunctionKey, Integer> cache = new HashMap<>();
    
    int function1(int value1, int value2){
        FunctionKey key = new FunctionKey(Functions.Function1, value1, value2);
        Integer result = cache.get(key);
        if (result==null){
            result = oldFunction1(value1, value2);
            cache.put(key, result);
        }
        return result;
    }
    
    如果您使用这样一个键构建一个HashMap,并将函数的结果作为值,那么您将能够在固定时间内检索旧值。如果映射中没有值,只需将这样一个键与新值一起存储即可

    功能1现在可能如下所示:

    enum Funtions{Funktion1, Funktion2, Funktion3};
    
    class FunctionKey(){
        public Functions function;
        public int value1
        public int value2
    
        public int hashCode(){
            int result = 1 + function.ordinal();
            result = result * 31 + value1;
            result = result * 17 + value2;
            return result;
        }
    
        public boolean equals(Object obj){
            if (!(obj instanceof FunctionKey))
                  return false;
            FunctionKey that = (FunctionKey) obj;
            return function == that.function && value1 == that.value1 && value2 == that.value2;
        }
    }
    
    Map<FunctionKey, Integer> cache = new HashMap<>();
    
    int function1(int value1, int value2){
        FunctionKey key = new FunctionKey(Functions.Function1, value1, value2);
        Integer result = cache.get(key);
        if (result==null){
            result = oldFunction1(value1, value2);
            cache.put(key, result);
        }
        return result;
    }
    
    Map cache=newhashmap();
    int函数1(int值1,int值2){
    FunctionKey key=新的FunctionKey(Functions.Function1,value1,value2);
    整数结果=cache.get(key);
    如果(结果==null){
    结果=旧函数1(值1,值2);
    cache.put(键、结果);
    }
    返回结果;
    }
    
    如果函数返回不同的数据类型,它会变得有点笨拙(也许每个函数一个映射就可以了)


    这个概念叫做缓存。

    创建某种哈希表?与链表相结合(在实现的地方可能会有点混乱-可能是某种帮助问题不在于Java中要使用的数据结构。我想这是关于要遵循的算法策略。我相信我们使用比较的逻辑中有一些东西可以改进…对不起,我的意思是将集合发送到将函数调用的类型作为第一个映射的键,将参数列表作为第二个映射的键。在大多数情况下,都是在固定时间内完成的。a q在Java中,uick搜索Memonization一词可以找到一系列有用的方法。有用且性能良好?谢谢,比较逻辑仍然存在:function==that.function&&value1==that.value1&&value2==that.value2。您可以在映射上推送比较逻辑,但随着映射的增长,比较的性能会更差。不,不会。试试看。HashMaps有固定的访问时间。每次获取时,这些比较只进行固定次数。需要多少次比较完全取决于映射的细节。但通常情况下,不管映射的增长有多大,平均应该少于三次。效果非常好-我可以改进我的算法的性能:went从20分钟到2分钟。谢谢!