Оптимизация кода Java
-
06-07-2019 - |
Вопрос
Как я могу оптимизировать этот код? Я сделал 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;
}
}
Решение
Выполните профилирование в нескольких типичных случаях использования и используйте эти данные, чтобы определить узкие места производительности. ТО , оптимизируйте этот код.
Не зная, где проблема с производительностью, вы можете потратить много времени и усилий, экономя микросекунды.
Другие советы
Я не уверен, что именно вы пытаетесь оптимизировать. Однако у вас есть пара 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 .
Не зря, но IP-адрес - это 4-байтовое целое число, как обычно это делается. Почему бы не кодировать это, а просто позволить:
int ipSrc = convertIpToInt(String ip);
if ( ipSrc == ipDest ) {
///
}
будь твоим сравнением. Р>
А для IPv6 вы можете использовать use long. Р>
Опять же, я бы, вероятно, использовал java.net.Inet4Address и сохранил их в наборе. Р>
Поскольку вы уже используете карту, почему бы не попробовать упрощенный подход? На полпути умная реализация Inet4Address.equals () будет выполнять целочисленное сравнение, а не сравнение строк.
Конечно, этот метод не работает, если вы хотите использовать подстановочные знаки ...: - /