Contenido de certificación
Buscar
Social
Ofertas laborales ES
« Gestión de hilos dentro de una aplicación web de Tomcat. | Main | Problema con iteración »
lunes
nov122012

Concatenar arrays

Por razones de rendimiento es mejor usar arrays que colecciones, siempre que sea posible o conveniente.

Sin embargo, el JDK no contiene métodos para realizar operaciones usuales con arrays, como concatenar.

Siguen dos ejemplos que permiten concatenar dos o varios arrays.

public static <T> T[] concat(final T[] first, final T[] second) {
   final T[] result = Arrays.copyOf(first, first.length + second.length);
   System.arraycopy(second, 0, result, first.length, second.length);
   return result;
}
  
@SafeVarargs
 public static <T> T[] concatAll(final T[] first, final T[]... others) {
     int totalLength = first.length;
     for (T[] array : others) {
         totalLength += array.length;
     }
     final T[] result = Arrays.copyOf(first, totalLength);
     int offset = first.length;
     for (T[] array : others) {
         final int length = array.length;
         System.arraycopy(array, 0, result, offset, length);
         offset += length;
     }
     return result;
 }

Reader Comments (13)

Voy a hacer una crítica sin ninguna mala intención:
No me gusta como empieza el post "Por razones de rendimiento es mejor usar arrays que colecciones, siempre que sea posible o conveniente". Yo lo diría al revés: A menos que haya muy buenas razones para creer que el uso de colecciones está causando un problema de rendimiento o uso excesivo de memoria, y hayamos hecho mediciones que prueben ese problema, es mejor usar colecciones que arrays.
Incluso si ese es el problema, antes de usar arrays aconsejaría probar las clases de Trove o fastutil que manejan colecciones de tipos primitivos en forma mas eficiente que las colecciones del JDK.
Y si aún así tenemos problemas de perfomance o uso de memoria, estamos trabando muy al límite. En ese caso tampoco usaría métodos auxiliares que usen generics o argumentos de largo variable, porque si mis arrays son arrays de primitivos se crean muchos objetos innecesarios por el tema del autoboxing.
Quedé muy negativo, lo se. ¡Perdón!

noviembre 12, 2012 | Unregistered CommenterPablo Grisafi

Las colecciones usan arrays internamente. En realidad son envolturas alrededor de implementaciones de arrays, y hay numerosas pruebas de rendimiento que demuestran lo que apunta la lectura del código fuente de las mismas.
La utilidad de las colecciones está fuera de duda, por la flexibilidad que aportan sus métodos; pero eso no las hace más eficientes, sino más convenientes.
Esos métodos de más arriba no están pensados para primitivas con autoboxing, sino para arrays de objetos creados por el desarrollador, en casos donde la eficiencia es más interesante que la flexibilidad de las colecciones. Por ejemplo, en codecs de audio o vídeo.

noviembre 12, 2012 | Registered Commenterchoces

Una clase bien conocida, ArrayList, usa internamente un Object[], como puede verse en su código fuente:

/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer.
*/
private transient Object[] elementData;

/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;

/**
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}

/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this(10);
}

noviembre 12, 2012 | Registered Commenterchoces

Personalmente creo que si uno busca rendimiento extremo entonces no debe usar Java, sino C++ (puro, no de M$, ni Sharp).
Me parece que hablar de rendimiento "fino" en un lenguaje que corre sobre una VM no es correcto.
Saludos!!

noviembre 12, 2012 | Unregistered CommenterDiego

La JVM moderna usa dos compiladores JIT, el C1 y el C2 (este último cuando se lanza como -server) que pueden no solo compilar a código nativo, sino almacenar el código ya compilado, y ejecutarlo tal cual.
La decisión de cuándo compilar y cuándo almacenar se basa en los llamados "hotspots" (de ahí el nombre como se conoce a la VM), es decir, bloques de código que se repiten un número predeterminado de veces.

Cuando se ejecutan esos "hotspots", el código Java se ejecuta tanto o más rápido que el resultado de compilar a código nativo off-line en otros lenguajes como C.
La ventaja de la VM es que el código que se ejecuta de manera ocasional se "interpreta" a partir del bytecode, y el que se ejecuta de manera intensiva, se ejecuta compilado a código nativo sobre la marcha, o directamente desde la versión compilada almacenada.

Por eso se puede hablar, con toda propiedad y corrección, de buen rendimiento en una VM.

En todo caso, lo que se trata aquí es de dilucidar alternativas en Java para la solución de determinados problemas, no en comparar soluciones en Java con las de otros lenguajes.

noviembre 12, 2012 | Registered Commenterchoces

De verdad, fuera del unboxin, se nota tanto usar arrays o arraylists?

Por otro lado... no hay una clase que haga esto en Guava?

Finalmente, como dice el primer comentario, no creo que el comienzo de este post sea muy afortunado. No creo que deba usarse arrays cuando "se pueda" porque son mas eficientes. A todo caso diria que hay que usarlos cuando la eficiecia sea realmente importante.

noviembre 14, 2012 | Registered Commentergolthiryus

Hace unos días, Jaroslav Tulach, Arquitecto jefe de NetBeans, publicó una entrada en su blog, titulada: "Cuando se tiene un martillo en la mano, todos los problemas parecen clavos".
Creo que uno de los objetos de un foro como éste consiste analizar una diversidad de herramientas, aparte de un martillo, para que los problemas no parezcan todos clavos.

Saliendo de metáforas, existen actitudes acomodaticias que aplican ciegamente las mismas técnicas a todo, sin pensar si existen alternativas más adecuadas.

Por cierto, el comienzo dice: si se puede y conviene, Con frecuencia se puede, y no conviene.

En aplicaciones como High Speed Trading, o codecs, por supuesto que se nota, y mucho.
Si se puede realizar con un array lo mismo que con una colección, sin renunciar a la conveniencia de determinados métodos de esta última, sigo pensando que es mejor usar un array.

noviembre 14, 2012 | Registered Commenterchoces

Medio un poco:
1) Si quieres rendimiento, arrays es mejor que colecciones.
2) Si quieres comodidad y más funcionalidad, colecciones es buena opción.
3) Si tienes problemas de rendimiento, una CPU más rápida te puede venir bien :) Si sigues teniendo problemas, escoge otro lenguaje que te permite atacar a memoria directamente (c o c++), si sigues teniendo problemas, pásate a Cobol, las instrucciones son más bestias pero más cercanas a la CPU, y si sigues teniendo problemas, vete a ensamblador, y programa directamente en la propia CPU :) Más nivel de abstracción no conozco.

En fin, las colecciones nacen como elementos que dan funcionalidad y se orientan y acercan a casos reales (tienen código por encima que se apoyan en array's), pero su rendimiento es menor que los propios array's.

Ahora bien, si quieres usar un algoritmo de, por ejemplo, ordenación, que supere a los algortimos de colección actuales, te animo a que lo propongas en las próximas especificaciones del lenguaje.

Saludos,

noviembre 24, 2012 | Registered Commenterjcarmonaloeches

Ya se ha hecho un cambio en los algoritmos de ordenación en JavaSE 1.7
Para las primitivas se cambió el Quicksort por el Dual Pivot Quicksort, y para las clases el MergeSort por TimSort.

noviembre 25, 2012 | Registered Commenterchoces

Choces, ¿te animas a escribir artículos explicativos sobre este tema, por ejemplo?
¿Cómo lo ves?

diciembre 5, 2012 | Registered Commenterjcarmonaloeches

Si te refieres a las implementaciones de sort en el JDK, podría hacerlo; lo mismo que a implementaciones alternativas de sort.
De todos modos, lo que más me interesa es que haya un debate técnico, y no una catarata de "opiniones" sin código que las respalde, como suele suceder, y que es lo que más desanima.

diciembre 5, 2012 | Registered Commenterchoces

ok, entendido tu punto de vista man ;)

diciembre 10, 2012 | Registered Commenterjcarmonaloeches

que les parece si hacemos un debate de quien crear el mejor metodo de ordenacion, el mas directo y mas rapido
que les parece se animan?

marzo 19, 2013 | Unregistered Commenterjava_kenyi

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>