código Otimização Java
-
06-07-2019 - |
Pergunta
Como posso otimizar esse código? Fiz IPFilter e eu preciso otimizá-lo.
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;
}
}
Solução
Perfil-lo através de alguns casos de uso típicos e usar esses dados para descobrir quais são os gargalos de desempenho são. THEN , otimizar o código.
Sem realmente saber onde o problema de desempenho é, você poderia gastar um monte de tempo e economia de esforço microssegundos.
Outras dicas
Eu não tenho certeza sobre o que exatamente você está tentando otimizar. No entanto, você tem um par de containsKey
seguido por get
. Uma otimização possível é usar get
e comparar com null
. Por exemplo, em vez de:
if (filter.containsKey(ip[level])) {
filter.get(ip[level])
}
Faça o seguinte:
IPFilter value = filter.get(ip[level]);
if (value != null) {
value.addIp(...);
}
Mas eu acho que a melhor dica que posso dar é: use um profiler. Se você estiver usando Eclipse, verifique TPTP .
Não é por nada, mas um endereço IP é um número inteiro de 4 byte, como é normalmente implementado. Por que não codificam a isso, e apenas deixá:
int ipSrc = convertIpToInt(String ip);
if ( ipSrc == ipDest ) {
///
}
ser a sua comparação.
E para IPv6, você poderia usar usar um longo.
Então, novamente, o que eu provavelmente fazer é usar java.net.Inet4Address e armazená-los em um conjunto.
Uma vez que você já está usando um mapa, por que não experimentar uma abordagem simplista? A implementação meio caminho inteligente de Inet4Address.equals () faria uma comparação inteiro, e não uma comparação de string.
É claro que este método divide, se você quer fazer wildcarding ...: - /