Pregunta

Me escribió un pequeño LINQ como DSL en la parte superior de la Google Colecciones

    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));
      }
   }

}

por lo que podía hacer colecciones de consulta de una manera más concisa legible

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

Me preocupa si este enfoque provocará una explosión de mini objetos y causar algunos problemas de recolección de basura (o cualquier otra cuestión)?

¿Fue útil?

Solución

Creo que Google utiliza Colecciones ejecución diferida para la mayoría de sus iteradores. ejecución diferida reduciría al mínimo el número de objetos intermedios creados ya que eliminaría la mayor parte de las listas intermedios / temporal que se podrían crear para cada llamada (donde, orderby, etc).

Básicamente, la cada elemento devuelto por currentlyAssigned.iterator () no se calcula hasta que llame iterator.next (). Hasta entonces, su currentlyAssigned iterables es sólo un conjunto de operaciones, nada más.

Su única preocupación sobre la explosión de mini-objetos si los objetos duran más tiempo que la duración de una sola operación elemento ... el uso de memoria máximo podría llegar a ser muy grande en ese caso y que potencialmente podría quedarse sin memoria en muy grande listas o si estaban convirtiendo los objetos (es decir, llamando ToUpper () en todas las cadenas o algo así). Esto sólo sería el caso si el resultado de que () era otra lista, a continuación, orderby () crea otra lista, así sucesivamente y así sucesivamente.

En cuanto a la manipulación de muchos objetos de breve duración GC, no hay problema. El moderno recolector de basura de Java muy optimizado para manejar ese comportamiento exacto.

Otros consejos

Creo que depende de cómo se comporta transformar, si es como un filtro lento, es decir, no adjunta una referencia a cada resultado. a continuación, su objeto más que bien sabia contar. La recolección de basura sabia, no se está manteniendo todas las referencias ocultas, una vez que se pierde la referencia de raíz todo el gráfico se vuelve inalcanzable y se recogió. camino a seguir este hombre es muy bien cuidado.

El recolector de basura tiene un código especial para los objetos de corta vida, y son muy muy barato de usar. Básicamente vez en cuando todos los objetos pequeños están marcados alcanzables y todos los demás objetos, se recupera de una sola vez.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top