0

このコードを最適化するにはどうすればよいですか? IPFilter を作成しましたが、最適化する必要があります。

package com.ipfilter;

import java.util.HashMap;
import java.util.Map;

/**
 *      IPFilter
 * 
 *      Loads given IP addresses to memory, so you can  easily check if ip addres has been blocked
 */

public class IPFilter {
        private Map<Integer, IPFilter> filter = new HashMap<Integer, IPFilter>();

        /**
         * Convert String ip address to Integer array and then calls add ip method
         * @param ip
         * @return
         */
        public void addIP(String ip)
        {
                int[] numbers = convert(ip);
                addIP(numbers, 0);
        }

        /**
         * Convert String ip address to Integer array
         * @param ip
         * @return
         */
        private int[] convert(String ip) {
                String[] strings = ip.split("\\.");
                int[] numbers = new int[strings.length];
                for(int i = 0; i < strings.length; i++)
                {
                        numbers[i] = Integer.parseInt(strings[i]);
                }
                return numbers;
        }

        /**
         * Add ip address to memory
         * @param ip
         * @param level
         */
        private void addIP(int[] ip, int level) {
                if(level < ip.length)
                {
                        if (filter.containsKey(ip[level])) {
                                filter.get(ip[level]).addIP(ip, level + 1);
                        } else {
                                filter.put(ip[level], new IPFilter());
                                filter.get(ip[level]).addIP(ip, level + 1);
                        }
                }
        }

        /**
         * Checks if ip address is in filter
         * @param ip
         * @return
         */
        public boolean isBlocked(String ip)
        {
                return isBlocked(filter, convert(ip), 0);
        }

        /**
         * Check if ip address is blocked
         * @param list
         * @param ip
         * @param level
         * @return
         */
        private boolean isBlocked(Map<Integer, IPFilter> list, int[] ip, int level)
        {
                if(list.containsKey(ip[level]))
                {
                        if(level < ip.length - 1)
                        {
                                return isBlocked(list.get(ip[level]).getList(), ip, level + 1);
                        }
                        else
                        {
                                return true;
                        }
                }
                else
                {
                        return false;
                }
        }       

        /**
         * Getter for list
         * @return
         */
        protected Map<Integer, IPFilter> getList() {
                return filter;
        }
}
4

3 に答える 3

9

いくつかの典型的なユースケースを通してプロファイリングし、そのデータを使用してパフォーマンスのボトルネックがどこにあるかを見つけます。THEN、そのコードを最適化します。

パフォーマンスの問題がどこにあるかを実際に知らなければ、マイクロ秒を節約するために多くの時間と労力を費やす可能性があります。

于 2009-09-11T19:27:47.420 に答える
2

何を最適化しようとしているのか正確にはわかりません。ただし、いくつかのcontainsKey後にget. 考えられる最適化は、 を使用getして比較することnullです。たとえば、次の代わりに:

 if (filter.containsKey(ip[level])) {
      filter.get(ip[level])
 }

以下をせよ:

 IPFilter value = filter.get(ip[level]);
 if (value != null) {
      value.addIp(...);
 }

しかし、私があなたに提供できる最善のヒントは、プロファイラーを使用することだと思います。Eclipse を使用している場合は、TPTPを確認してください。

于 2009-09-11T19:32:47.517 に答える
2

無駄ではありませんが、IP アドレスは通常実装されている 4 バイトの整数です。それにエンコードして、次のようにします。

int ipSrc = convertIpToInt(String ip); 
if ( ipSrc == ipDest ) { 
  /// 
} 

あなたの比較になります。

IPv6 の場合は、long を使用できます。

繰り返しになりますが、私がおそらく行うことは、java.net.Inet4Address を使用してそれらを Set に格納することです。

既にマップを使用しているので、単純化したアプローチを試してみませんか? Inet4Address.equals() の中途半端な実装では、文字列の比較ではなく、整数の比較が行われます。

もちろん、ワイルドカードを使用したい場合、この方法は機能しません... :-/

于 2009-09-11T19:45:34.540 に答える