2013-07-30 4 views
-1

У меня есть две реализации такой же функциональности, как они выглядят следующим образом.Эффективность Java для циклов

private String mapToString(Map<String, String> map) 
     throws UnsupportedEncodingException 
{ 
    if(map.isEmpty()) 
    { 
     throw new IllegalArgumentException("Map cannot be empty"); 
    } 

    StringBuilder sb = new StringBuilder(); 

    for(Map.Entry<String, String> pair : map.entrySet()) 
    { 
     if(pair.getKey() == null) 
     {throw new IllegalArgumentException("Invalid parameter:" + 
       " Parameters key is null");} 

     if(pair.getValue() == null) 
     {throw new IllegalArgumentException("Invalid parameter:" + 
       " Parameters value is null");} 


     // Because the map cannot be empty and can be of arbitrary size it 
     // is it more efficient to append the _ at the end of each cycle and 
     // remove the extra _ when the string is done being built. 

     sb.append(URLEncoder.encode(pair.getKey(), "UTF-8")); 
     sb.append('-'); 
     sb.append(URLEncoder.encode(pair.getValue(), "UTF-8")); 
     sb.append('_'); 
    } 

    String result = sb.toString(); 

    // Remove the extra _ 
    return result.substring(0, result.length() - 1); 
} 

и второй один

private String mapToString(Map<String, String> map) 
     throws UnsupportedEncodingException 
{ 
    if(map.isEmpty()) 
    { 
     throw new IllegalArgumentException("Map cannot be empty"); 
    } 

    StringBuilder sb = new StringBuilder(); 

    for(Map.Entry<String, String> pair : map.entrySet()) 
    { 
     if(pair.getKey() == null) 
     {throw new IllegalArgumentException("Invalid parameter:" + 
       " Parameters key is null");} 

     if(pair.getValue() == null) 
     {throw new IllegalArgumentException("Invalid parameter:" + 
       " Parameters value is null");} 

     if(sb.length() != 0) 
     { 
      sb.append('_'); 
     } 
     sb.append(URLEncoder.encode(pair.getKey(), "UTF-8")); 
     sb.append('-'); 
     sb.append(URLEncoder.encode(pair.getValue(), "UTF-8")); 
    } 

    return sb.toString(); 
} 

Каждая версия этого метода берет карту строк, которые гарантированно не может быть пустым и создает строку из них. Строка начинается с ключа, за которым следует a - тогда значение. Каждая из этих пар разделяется символом _.

key1-value1_key2-value2_key3-value3_...... 

Мои два варианта, чтобы проверить, чтобы увидеть, если строка пуста и не поместить _ разделитель и сохранить себя создание подстроку в конце. Или не делайте проверку, добавьте _ в конце цикла, а затем используйте подстроку, чтобы удалить лишний _, который будет получен.

Мне любопытно, что было бы более эффективно для произвольно большой карты.

+1

Преждевременная оптимизация? Обычно, когда ваш код работает медленно, для улучшения требуется фундаментальное изменение алгоритма, а не такое маленькое. И оптимизации, подобные этому, полезны только для рассмотрения *, когда * ваш код работает медленно, а не раньше. –

+1

Вы можете сделать очень большую карту и [попробовать сами] (http://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-java). – ajp15243

+0

Возможно, это преждевременная оптимизация, однако оба они очень читаемы, поэтому я не вижу проблемы с попыткой использовать наиболее эффективную версию. – assylias

ответ

3

Решающий фактор между этими двумя реализациями должен действительно сходить на удобочитаемость. Сказав это, ваша первая реализация, которая использует substring, будет дороже, и поскольку я не вижу различий в различии между ними, я бы предпочел второй вариант. Альтернативой было бы просто использовать boolean флаг вместо проверки sb.length():

append = false; 

for (...) { 
    ... 

    if (append) { 
     sb.append('_'); 
    } 

    ... 

    append = true; 
} 
Смежные вопросы