Efficiency of the way comparator works

跟風遠走 提交于 2019-11-30 23:45:48

On average, your sort algorithm will call complexOperation() method about log2N times for an array of N students. If the operation is really slow, you may be better off running it once for each student. This could bring an order of magnitude improvement for an array of 1,000 students.

However, you do not have to do it explicitly: you could make complexOperation(...) store the result for each student, and then return the cached value on subsequent requests:

private Map<Student,Integer> cache = new HashMap<Student,Integer>();

private int complexOperation(Student s) {
    // See if we computed the rank of the student before
    Integer res = cache.get(s);
    if (res != null) {
        // We did! Just return the stored result:
        return res.intValue();
    }
    ... // do the real computation here
    // Save the result for future invocations
    cache.put(s, result);
    return result;
}

Note that in order for this approach to work, Student class needs to implement hashCode and equals.

Basically, you want to compare students by comparing some values that each maps to. This is usually done by

    static Comparator<Student> comparator()
    {
        return Comparator.comparing( Foo::complexOperation );
    }

However, since the function complexOperation is too expensive, we want to cache its results. We can have a general purpose utility method Function cache(Function)

    static Comparator<Student> comparator()
    {
        return Comparator.comparing( cache(Foo::complexOperation) );
    }

In general, it is better that the caller can supply a Map as the cache

public static <K,V> Function<K,V> cache(Function<K,V> f, Map<K,V> cache)
{
    return k->cache.computeIfAbsent(k, f);
}

We can use IdentityHashMap as the default cache

public static <K,V> Function<K,V> cache(Function<K,V> f)
{
    return cache(f, new IdentityHashMap<>());
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!