Domanda

ho scritto un po 'di Linq come DSL in cima Google Collezioni

    public class IterableQuery {

   public static <T> Where<T> from(Iterable<T> originalCollection) {
      return  new Where<T>( Iterables.transform(originalCollection, IterableQuery.<T>SAME()));
   }

   private static <T> Function<T, T> SAME() {
      return new Function<T, T>(){
         public T apply(T arg0) {
            return arg0;
         }
      };
   }


   public static class SelectOrderBy<T>{

      private final Iterable<T> iterable;

      public SelectOrderBy(Iterable<T> iteable) {
         this.iterable = iteable;
      }

      public  SelectOrderBy<T> orderyBy( Comparator<T> sort ){
          Ordering.forComparator(sort).sort((List< ? extends T>) iterable);
          return new SelectOrderBy<T>( iterable);
      }

      public  <F> Iterable<F> select(  Function<? super T,? extends F> function){
         return Iterables.transform(iterable, function);
      }
      public  Iterable<T> selectEveryThing( ){
         return iterable;
      }
   }


   public static class Where<T>{

      private final Iterable<T> iterable;

      public Where(Iterable<T> iterable) {
         this.iterable = iterable;
      }

      public    SelectOrderBy<T> where(Predicate<T> predicate) {
         return  new SelectOrderBy<T>( Iterables.filter(iterable, predicate));
      }
   }

}

così ho potuto fare collezioni di query in modo leggibile più conciso

 Iterable<? extends NewOrder > currentlyAssigned = 
         IterableQuery.
          from(orders).
          where(placedInLast10Days).
          orderBy(lastName). 
          select(orderToNewOrder);

Sono preoccupato se questo approccio causerà un'esplosione di mini oggetti e causare alcuni problemi di Garbage Collection (o qualsiasi altra questione)?

È stato utile?

Soluzione

Credo che Google utilizza Collezioni esecuzione differita per la maggior parte dei suoi iteratori. esecuzione differita ridurrebbe al minimo il numero di oggetti intermedi creati come sarebbe eliminare la maggior parte delle liste intermedi / temporaneo che potrebbero essere creati per ogni chiamata (dove, orderby, ecc).

In sostanza, l'ogni elemento restituito da currentlyAssigned.iterator () non viene calcolato fino a quando si chiama iterator.next (). Fino ad allora, la tua currentlyAssigned iterabile è solo un insieme di operazioni, niente di più.

La vostra unica preoccupazione per l'esplosione di mini-oggetti se tali oggetti durano più a lungo rispetto alla durata di una singola operazione elemento ... l'utilizzo della memoria di picco potrebbe ottenere abbastanza grande in quel caso e si potrebbe potenzialmente a corto di memoria molto grande liste o se si stesse convertendo gli oggetti (ad esempio chiamando ToUpper () su tutte le stringhe o qualcosa del genere). Questo sarebbe solo il caso se il risultato di dove () è stato un altro elenco, quindi orderby () ha creato un altro elenco, così via e così via.

Per quanto riguarda la gestione di molti oggetti vissuti brevi GC, non c'è nessun problema. Il moderno Java garbage collector pesantemente ottimizzato per gestire tale comportamento esatto.

Altri suggerimenti

Credo che dipende da come si comporta trasformare, se come un filtro pigro, vale a dire non si collega un riferimento a ogni risultato. poi contare saggio il suo oggetto più di OK. garbage collection saggio, non stanno mantenendo i riferimenti nascosti, una volta che si perde il riferimento principale l'intero grafico diventa irraggiungibile e viene raccolto. strada da percorrere l'uomo questo è davvero bello.

Il garbage collector ha codice speciale per gli oggetti di breve durata, e sono molto molto economico da usare. Fondamentalmente tanto tutti oggetti giovani raggiungibili sono assegnati ed ogni altro oggetto venga recuperato in un sol.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top