2016-11-28 2 views
1

тематическое исследование
у меня есть метод, который сканировать файловую систему для определенных записей, а когда нашли, хранит их в качестве новых объектов. Эти объекты включают пару строк для позиции входа и флагов, которые представляют состояние записи.

Как каждый новый объект I instanciate занимает> 16 байт, если найдено 1000 записей, я использую (16 * 1000) байтов! Поскольку мне нужен только один экземпляр за раз, я хотел бы повторно использовать один объект (то есть, используя new за один раз) и обновлять его поля.Повторное использование одного объекта вместо того, чтобы создавать новые

Вот как я имею дело с объектами сейчас:

for (final Object object : scanFor(PATTERN)) { 
    if (aName.equals(object.getName()) { 
    ... use the object 
    } 
} 

Я думал, что я могу использовать ту же технику, как ResultSet.
Любое предложение?

P.S. Я знаю, что 16kb памяти ничего, но это пример.

EDIT: Я вижу, что кто-то проголосовал за закрытие моего вопроса, потому что это неясно. Я действительно не знаю, что еще писать, чтобы быть честным.

EDIT, реальный код:
Caller:

DspPgmRef dspPgmRef = new DspPgmRef("MYLIBRARY", "*ALL", J400Type.ALL); 
dspPgmRef.addFilter(DspPgmRefEntryField.REFERENCED_OBJECT, name); 

for (final DspPgmRefEntry entry : dspPgmRef.run()) { 
    if (entry.referencedObject.equals(name)) { 
     users.add(J400ObjectFactory.get("*LIBL", entry.object)); 
    } 
} 

DspPgmRef реализация:

public final class DspPgmRef implements J400Command<List<DspPgmRefEntry>> 
{ 
    /** 
    * Rappresenta un valore di ritorno del comando 
    */ 
    public static class DspPgmRefEntry 
    { 
     public final String library; 
     public final String object; 
     public final String referencedLibrary; 
     public final String referencedObject; 
     public final String referencedType; 

     public DspPgmRefEntry(
      final String library, 
      final String object, 
      final String referencedLibrary, 
      final String referencedObject, 
      final String referencedType) { 
     this.library = library; 
     this.object = object; 
     this.referencedLibrary = referencedLibrary; 
     this.referencedObject = referencedObject; 
     this.referencedType = referencedType; 
     } 
    } 

    /** 
    * Campi dei riferimenti ritornati dal comando 
    */ 
    public enum DspPgmRefEntryField 
    { 
     LIBRARY("WHLIB"), 
     OBJECT("WHPNAM"), 
     REFERENCED_LIBRARY("WHLNAM"), 
     REFERENCED_OBJECT("WHFNAM"), 
     REFERENCED_TYPE("WHOTYP"); 

     /** 
     * Nome reale del campo di database 
     */ 
     public final String value; 

     private DspPgmRefEntryField(final String value) { 
     this.value = value; 
     } 
    } 

    private final String _library; 
    private final String _object; 
    private final J400Type _type; 
    private final Map<DspPgmRefEntryField, String> _filters; 

    { 
     _filters = new EnumMap<>(DspPgmRefEntryField.class); 
    } 

    public DspPgmRef(final String library, final String object, final J400Type type) { 
     _library = library; 
     _object = object; 
     _type = type; 
    } 

    public DspPgmRef(final J400GenericObject object) { 
     this(object.getLibrary(), object.getName(), object.getType()); 
    } 

    @Override 
    public List<DspPgmRefEntry> run() { 
     final String tempLibrary = J400Util.getRandomAS400String(); 
     final String tempFile = J400Util.getRandomAS400String(); 
     final int filtersSize = _filters.size(); 

     final StringBuilder builder = new StringBuilder(120 + filtersSize * 20); 
     builder.append("DSPPGMREF PGM("); 
     builder.append(_library); 
     builder.append("/"); 
     builder.append(_object); 
     builder.append(") OUTPUT(*OUTFILE) OBJTYPE("); 
     builder.append(_type.ASType); 
     builder.append(") OUTFILE("); 
     builder.append(tempLibrary); 
     builder.append("/"); 
     builder.append(tempFile); 
     builder.append(")"); 

     final J400Connection connection = J400Connection.instance(); 
     connection.createLibrary(tempLibrary, "Libreria temporanea per DSPDBR"); 

     if (!connection.executeCommand(builder.toString()).containsKey("CPF3030")) { 
     return Collections.EMPTY_LIST; 
     } 

     builder.delete(0, builder.length()); 
     builder.append("select distinct WHPNAM, WHLNAM, WHFNAM, WHOTYP from "); 
     builder.append(tempLibrary); 
     builder.append("."); 
     builder.append(tempFile); 

     if (filtersSize > 0) { 
     builder.append(" where "); 

     for (final Entry<DspPgmRefEntryField, String> filter : _filters.entrySet()) { 
      builder.append(filter.getKey().value); 
      builder.append(" = '"); 
      builder.append(filter.getValue()); 
      builder.append("' and "); 
     } 

     final int stringLenght = builder.length(); 
     builder.delete(stringLenght - 5, stringLenght); 
     } 

     PreparedStatement statement = null; 
     ResultSet result = null; 

     try { 
     statement = connection.getConnection().prepareStatement(builder.toString()); 
     result = statement.executeQuery(); 

     final List<DspPgmRefEntry> references = new ArrayList<>(128); 

     while (result.next()) { 
      references.add(new DspPgmRefEntry(
        _library, 
        result.getString(DspPgmRefEntryField.OBJECT.value).trim(), 
        result.getString(DspPgmRefEntryField.REFERENCED_LIBRARY.value).trim(), 
        result.getString(DspPgmRefEntryField.REFERENCED_OBJECT.value).trim(), 
        result.getString(DspPgmRefEntryField.REFERENCED_TYPE.value).trim())); 
     } 

     return Collections.unmodifiableList(references); 
     } catch (final SQLException e) { 
     e.printStackTrace(); 
     } finally { 
     try { 
      if (result != null) { 
       result.close(); 
      } 

      if (statement != null) { 
       statement.close(); 
      } 
     } catch (final SQLException e) { 
      e.printStackTrace(); 
     } 

     connection.deleteLibrary(tempLibrary); 
     } 

     return Collections.EMPTY_LIST; 
    } 

    public void addFilter(final DspPgmRefEntryField field, final String value) { 
     _filters.put(field, value); 
    } 

    public void removeFilter(final DspPgmRefEntryField field) { 
     _filters.remove(field); 
    } 

    public void clearFilters() { 
     _filters.clear(); 
    } 
} 
+0

Как насчет использования лямбда-функции в scanFor? – brummfondel

+0

@brummfondel mmmh Я не могу понять, что вы имеете в виду, можете ли вы объяснить немного больше? – LppEdd

+0

Пожалуйста, отправьте scanFor для лучшей помощи. – brummfondel

ответ

1

Давайте предположим, что вы предлагаете влияние на производительность и код smelliness о возвращении такой же экземпляр объекта от scanFor Метод в этом фрагменте:

for (final Object object : scanFor(PATTERN)) { 
    if (aName.equals(object.getName()) { 
    ... use the object 
    } 
} 

В зависимости от деталей остальной части кода (например, как часто equals проверка верно и то, что происходит в ... use the object), это может быть действительно очень большая экономия в размере распределения , Это, однако, нарушает общепринятое поведение Iterable<T>.iterator().next() - это то, что он возвращает уникальный объект каждый раз. Это обсуждалось на уровне some length before. Если вы оцениваете увеличение производительности, которое важно для вас, используя этот трюк, оно все равно может стоить, но, как всегда, измеряется.

Java Mission Control входит в комплект (Oracle) JDK и доступен для некоммерческого использования и может измерять актуальные тарифы на размещение объектов и местоположения. Вы можете использовать это, чтобы проверить, являются ли временные объекты значительной частью вашего общего распределения (в некоторых случаях анализ inlining + escape может быть полностью устранен, что делает вашу предполагаемую проблему проблемой).

+0

В основном вы предлагаете создать собственный итератор, который всегда возвращает тот же объект, только с измененными свойствами. – LppEdd

+0

И да, я абсолютно должен научиться использовать управление миссией! Ты прав! – LppEdd

+0

@LppEdd - чтобы быть ясным, вот что я думал, что вы предлагали, и я излагал некоторые из плюсов и минусов. Вы сказали: «Поскольку мне нужен только один экземпляр за раз, я хотел бы повторно использовать один объект (то есть, используя новый за один раз) и обновлять его поля». - и затем вы показали цикл, который использует foreach (требующий Iterable). Вы можете использовать свой подход «один объект, мутированный» с помощью Iterable или просто изменить структуру цикла и избежать Iterable, что может быть немного яснее (поскольку будущий читатель кода может явно видеть, что один объект изменяется снова и снова). – BeeOnRope

Смежные вопросы