La forma más rápida de duplicados de un array en JavaScript – slice vs ‘para’ bucle

Con el fin de duplicados de un array en JavaScript: ¿cuál de los siguientes es más rápido de usar?

Rebanada método

var dup_array = original_array.slice();

For bucle

for(var i = 0, len = original_array.length; i < len; ++i)
   dup_array[i] = original_array[i];

Sé que ambas maneras de hacer sólo una copia superficial: si original_array contiene referencias a objetos, los objetos no ser clonado, pero sólo las referencias se pueden copiar, y por lo tanto, las matrices tiene referencias a los mismos objetos.
Pero este no es el punto de esta pregunta.

Estoy pidiendo sólo acerca de la velocidad.

  • jsben.ch/#/wQ9RU <= un punto de referencia para las formas más comunes para clonar una matriz
InformationsquelleAutor Marco Demaio | 2010-10-20

18 Kommentare

  1. 734

    Hay al menos 5 (!) formas de clonar una matriz:

    • bucle
    • rebanada
    • Matriz.a partir de()
    • concat
    • propagación del operador (el más RÁPIDO)

    Ha habido un huuuge Puntos de referencia de subproceso, proporcionando la siguiente información:

    • para parpadeo navegadores slice() es el método más rápido, concat() es un poco más lento, y while loop es de 2,4 x más lento.

    • para otros navegadores while loop es el método más rápido, ya que los navegadores no tienen optimizaciones internas para slice y concat.

    Esto sigue siendo cierto en Julio de 2016.

    A continuación son secuencias de comandos simples que usted puede copiar y pegar en el navegador de la consola y ejecutar varias veces para ver la imagen. Que la salida de milisegundos, menos es mejor.

    bucle while

    n = 1000*1000;
    start = + new Date();
    a = Array(n); 
    b = Array(n); 
    i = a.length;
    while(i--) b[i] = a[i];
    console.log(new Date() - start);

    rebanada

    n = 1000*1000;
    start = + new Date();
    a = Array(n); 
    b = a.slice();
    console.log(new Date() - start);

    Por favor, tenga en cuenta que estos métodos es el clon de la Matriz propio objeto, contenido de la matriz, sin embargo, son copiados por referencia y no son profundas clonado.

    origAr == clonedArr //returns false
    origAr[0] == clonedArr[0] //returns true
    • bien hecho! Esta podría ser la mejor respuesta ahora. Te gustaría ser capaz de explicar por qué la simple prueba realizada por lincolnk (es la respuesta anterior, stackoverflow.com/a/3978716/260080 ) da el resultado opuesto, donde slice es el más rápido de lo que el bucle? Me pregunto si es causada por el tipo de elementos en la matriz, en su ensayo estaban todos los números, en su son una mezcla de cadenas y objetos.
    • Marco, tiene usted toda la razón, el almacenamiento de datos de un tipo de velocidades de una matriz. Google ha escrito en alguna parte, pero siempre puedes comprobarlo jsperf.com/new-array-vs-splice-vs-slice/25 a sí mismo sin Embargo, la mayor diferencia la hace el hormigón motor de la realización. Los algoritmos de evolucionar a partir de construir para construir. Por otro lado, podemos predecir la evolución a la hora de saber la arquitectura del motor. @lincolnk la evaluación comparativa de resultados de buscar similares a los jsperf.com/new-array-vs-splice-vs-slice/11, octubre ’10 está en algún lugar cerca de Chrome 19 y FireFox 10. Oh, segmento es el más corto, a continuación, concat 🙂
    • sin emociones, sólo puntos de referencia jsperf.com/new-array-vs-splice-vs-slice/31
    • Entonces, ¿qué? Caso de prueba resultados: Firefox 30 de la noche todavía es ~230% más rápido que Chrome. Comprobar el código fuente de V8 para splice y usted será sorprendido (aunque…)
    • por desgracia para corto matrices la respuesta es muy diferente. Por ejemplo, la clonación de una matriz de oyentes antes de llamar a cada uno de ellos. Dichas matrices son a menudo pequeñas, generalmente de 1 elemento.
    • He probado hoy 2015-05-04, el método más rápido en Chrome 42 para Windows y para Android .concat()
    • Felicidades para la evaluación comparativa, demostró respuesta, buen trabajo
    • Los gráficos en los que los puntos de referencia de la página muestran que, al menos desde Chrome 34, el método más rápido ha sido consistentemente el bucle while pre-asignados. Es mejor que todos los otros métodos en todos los navegadores por mucho.
    • jsperf es hacia abajo. Mierda para referirse a ella, registrar los datos la próxima vez directamente aquí.
    • Te perdiste este método: A.map(function(e){return e;});
    • Al menos a partir de 9.1.2 Safari tiene el sector/concat perf mejoras, que son alrededor de 20 veces más rápido que el tiempo.
    • Usted está escribiendo sobre parpadeo los navegadores. No parpadeo sólo un motor de diseño, que afecta principalmente a la representación de HTML, y por lo tanto sin importancia? Pensé que nosotros preferimos hablar de V8, el mono araña y sus amigos aquí. Solo una cosa que me confundió. Ilumíname, si estoy equivocado.
    • WARNING: .slice, spread, concat, Array.from no clon objeto en la matriz. El uso de un bucle o una profunda clon lib
    • FYI: El ‘while’ versión es lento como el infierno en el IE. Probablemente yo uso slice a ser consistente.
    • Queridos @Dan escribió spread operator (FASTEST) pero no dar un ejemplo rápido! : D por Favor, agregue un ejemplo!!

  2. 224

    Técnicamente slice es la manera más rápida. Sin embargo, es incluso más rápido si usted agregue el 0 comenzar índice.

    myArray.slice(0);

    es más rápido que

    myArray.slice();

    http://jsperf.com/cloning-arrays/3

    • Cierto, alos aquí jsperf.com/new-array-vs-splice-vs-slice/19
    • Y es myArray.slice(0,myArray.length-1); más rápido que myArray.slice(0); ?
    • hecho acabo de arr.slice() para copiar la matriz y funcionó bien, gracias a cada uno
    • te has bajado el último elemento de la matriz. Copia completa de la matriz.slice(0) o de la matriz.slice(0, array.de longitud)
    • gracias, for-unshift!
  3. 121

    lo que acerca de es6 manera?

    arr2 = [...arr1];
    • si se convierte con babel: [].concat(_slice.call(arguments))
    • No estás seguro de dónde arguments viene… creo que su babel de salida es mezclando un par de características diferentes. Es más probable que se arr2 = [].concat(arr1).
    • es diferente de arr2 = [...arr1]. [...arr1] sintaxis va a convertir agujero para undefined. Por ejemplo, arr1 = Array(1); arr2 = [...arr1]; arr3 = [].concat(arr1); 0 in arr2 !== 0 in arr3.
    • He probado esto en mi navegador (Chrome 59.0.3071.115) en contra de Dan respuesta anterior. Era más de 10 veces más lento .slice(). n = 1000*1000; start = + new Date(); a = Array(n); b = [...a]; console.log(new Date() - start); // 168
    • Manera más simple. JS tiene esto sólo en el 2015… lo malo el idioma era antes (todavía lejos de ser decente).
    • Todavía no clonar algo como esto: [{a: 'a', b: {c: 'c'}}]. Si c‘s se cambia el valor en el «duplicado» de la matriz, se va a cambiar en la matriz original, ya que es sólo referencial copia, no un clon.
    • Como @TranslucentCloud se mencionó, no es todavía la referencia. Acabo de tener una muy muy confuso momento en que fue […baseSet, …baseSet] para duplicar una matriz (para un juego de Memoria) y finalmente me encontré con que había una situación de referencia. He utilizado lodash del cloneDeep para clonar mi array de objetos. El pensamiento de volver a visitar este post y el comentario… la Próxima vez me voy a leer todos los comentarios primero!

  4. 42

    Manera más fácil de profunda clon Matriz o un Objeto:

    var dup_array = JSON.parse(JSON.stringify(original_array))
    • Nota importante para los principiantes: porque depende de JSON, este también hereda sus limitaciones. Entre otras cosas, eso significa que la matriz no puede contener undefined o cualquier functions. Tanto de aquellos que serán convertidos en null para usted durante el JSON.stringify proceso. Otras estrategias, tales como (['cool','array']).slice() no va a cambiar sino que también no profundo clonar objetos dentro de la matriz. Así que hay un equilibrio.
    • Muy mala perf y no trabajar con objetos especiales como DOM, fecha, regexp, función … o prototipos de objetos. No admiten referencias cíclicas. Nunca se debe usar JSON para la profundidad de clon.
    • peor manera posible! Utilizar sólo si por algún problema de todos los demás no funciona. Es lento, los recursos de la intensa y tiene todas JSON limitaciones ya mencionadas en los comentarios. No puede imaginar cómo se obtuvo 25 votos.
    • En lo profundo de copias matrices con las primitivas, y donde las propiedades son matrices con más primitivas/matrices. Para que está bien.
    • es seguro fácil y muy conocido de la solución, pero me pregunto si es rápido
    • He probado esto en mi navegador (Chrome 59.0.3071.115) en contra de Dan respuesta anterior. Fue casi 20 veces más lento .slice(). n = 1000*1000; start = + new Date(); a = Array(n); var b = JSON.parse(JSON.stringify(a)) console.log(new Date() - start); // 221
    • Gracias, eso es en realidad la única manera que he encontrado para hacer una copia decente de mi matriz 😀

  5. 29
    var cloned_array = [].concat(target_array);
    • Por favor explique lo que esto hace.
    • Mientras este fragmento de código se puede responder a la pregunta, no se provee de un contexto para explicar cómo o por qué. Considerar la adición de una frase o dos para explicar su respuesta.
    • Odio este tipo de comentarios. Es obvio lo que hace!
    • Una respuesta simple para un simple quetions, no hay gran historia para leer. Me gusta este tipo de respuestas +1
    • «Estoy pidiendo sólo acerca de la velocidad» – Esta respuesta no da ninguna indicación sobre la velocidad. Esa es la principal pregunta que se le formuló. brandonscript tiene un buen punto. Se necesita más información para considerar esto una respuesta. Pero si se tratara de una simple pregunta, esta sería una excelente respuesta.
  6. 25

    Puse una rápida demostración: http://jsbin.com/agugo3/edit

    Mis resultados en Internet Explorer 8 156, 782, y 750, lo cual indicaría slice es mucho más rápido en este caso.

    • No olvides que el costo adicional de que el recolector de elementos no utilizados si usted tiene que hacer esto muy rápido mucho. Me estaba copiando cada vecino de la matriz para cada célula de mi autómatas celulares utilizando rebanada y era mucho más lento que el de la reutilización de una matriz anterior y copia de los valores. Chrome indica aproximadamente el 40% del total del tiempo se dedicó a la recolección de basura.
  7. 19

    a.map(e => e) es otra de las alternativas para este trabajo. A partir de hoy .map() es muy rápido (casi tan rápido como .slice(0)) en Firefox, pero no en Chrome.

    Por otro lado, si una matriz es multi-dimensional, puesto que las matrices son objetos, y los objetos son los tipos de referencia, ninguno de la división o concat métodos será una cura… Así que una forma adecuada de la clonación de una matriz es una invención de Array.prototype.clone() de la siguiente manera.

    JS:

    Array.prototype.clone = function(){
      return this.map(e => Array.isArray(e) ? e.clone() : e);
    };
    
    var arr = [ 1, 2, 3, 4, [ 1, 2, [ 1, 2, 3 ], 4 , 5], 6 ],
        brr = arr.clone();
    brr[4][2][1] = "two";
    console.log(JSON.stringify(arr));
    console.log(JSON.stringify(brr));

  8. 14

    Manera más rápida para Clonar Matriz

    Hice esta muy claro la utilidad de la función a prueba el tiempo que se tarda para clonar una matriz. No es 100% confiable sin embargo, se puede dar una masiva idea de por cuánto tiempo se necesita para clonar una matriz:

    function clone(fn) {
        const arr = [...Array(1000000)];
        console.time('timer');
        fn(arr);
        console.timeEnd('timer');
    }

    Y probado enfoque diferente:

    1)   5.79ms -> clone(arr => Object.values(arr));
    2)   7.23ms -> clone(arr => [].concat(arr));
    3)   9.13ms -> clone(arr => arr.slice());
    4)  24.04ms -> clone(arr => { const a = []; for (let val of arr) { a.push(val); } return a; });
    5)  30.02ms -> clone(arr => [...arr]);
    6)  39.72ms -> clone(arr => JSON.parse(JSON.stringify(arr)));
    7)  99.80ms -> clone(arr => arr.map(i => i));
    8) 259.29ms -> clone(arr => Object.assign([], arr));
    9) Maximum call stack size exceeded -> clone(arr => Array.of(...arr));

    ACTUALIZACIÓN:

    Nota: de todos ellos, la única manera de profunda clon de una matriz mediante el uso de JSON.parse(JSON.stringify(arr)).

    Dicho esto, no utilice el arriba si su matriz pueden incluir funciones como devolverá null.
    Gracias @GilEpshtain para esta actualización.

    • Traté de benchmarking su respuesta y me dieron resultados muy diferentes: jsben.ch/o5nLG
    • las pruebas podrían cambiar dependiendo de la ur máquina de curso. Sin embargo, siéntase libre de actualización de la respuesta con el resultado de su prueba. Buen trabajo!
    • Me gusta tu respuesta mucho, sin embargo trato de su prueba y conseguir que arr => arr.slice() es el más rápido.
    • Gracias por la ejecución de estas pruebas @GilEpshtain! El resultado va a cambiar, dependiendo de su máquina. He notado que por encima de la adjunta clon de la función. Creo que la principal conclusión es que algunos métodos son sustancialmente más rápido que otros. Especialmente cuando se trata de grandes cantidades de datos. Es ese sentido?
    • su actualización no es correcto, debido al hecho de que los métodos no son serializables. Por ejemplo: JSON.parse(JSON.stringify([function(){}])) de salida será de [null]
    • Gracias @GilEpshtain, yo no sabía eso 🙂 voy a hacer una actualización

  9. 7

    Echa un vistazo a: enlace. No se trata de velocidad, sino de comodidad. Además como se puede ver sólo puede utilizar slice(0) en tipos primitivos.

    Para hacer una copia independiente de una matriz en lugar de una copia de la referencia a ella, se puede utilizar la matriz de la rebanada método.

    Ejemplo:

    Para hacer una copia independiente de una matriz en lugar de una copia de la referencia a ella, se puede utilizar la matriz de la rebanada método.

    var oldArray = ["mip", "map", "mop"];
    var newArray = oldArray.slice();

    Para copiar o clonar un objeto :

    function cloneObject(source) {
        for (i in source) {
            if (typeof source[i] == 'source') {
                this[i] = new cloneObject(source[i]);
            }
            else{
                this[i] = source[i];
      }
        }
    }
    
    var obj1= {bla:'blabla',foo:'foofoo',etc:'etc'};
    var obj2= new cloneObject(obj1);

    Fuente: enlace

    • El tipos primitivos observación se aplica a los for bucle en la pregunta así.
    • si yo fuera la copia de un array de objetos, yo esperaría que la nueva matriz para hacer referencia a los mismos objetos, en lugar de la clonación de los objetos.
  10. 7

    Como @Dan dijo: «Esta respuesta se vuelve obsoleto rápidamente. Uso puntos de referencia para comprobar la situación real», hay una respuesta específica de jsperf que no ha tenido una respuesta por sí mismo: mientras:

    var i = a.length;
    while(i--) { b[i] = a[i]; }

    había 960,589 ops/seg con el subcampeón a.concat() en 578,129 ops/seg, que es de 60%.

    Este es el más reciente de Firefox (40) de 64 bits.


    @aleclarson creado una nueva, más fiable de referencia.

    • Usted realmente debe vincular el jsperf. El que usted está pensando de que está roto, debido a una nueva matriz se crea en cada caso de prueba, excepto la ‘while’ de la prueba.
    • jsperf.com/new-array-vs-splice-vs-slice/19
    • He hecho una nueva jsperf que es más preciso: jsperf.com/clone-array-3
    • El 60% de qué? 60% más rápido?
    • 587192 es de ~60% (61.1…) de 960589.
  11. 6

    Depende del navegador. Si usted mira en el post del blog De la matriz.el prototipo.slice vs manual de creación de la matriz de, no es una guía general para el desempeño de cada uno de ellos:

    La forma más rápida de duplicados de un array en JavaScript - slice vs 'para' bucle

    Resultados:

    La forma más rápida de duplicados de un array en JavaScript - slice vs 'para' bucle

    • arguments no es un buen matriz y a él usando call a la fuerza slice a ejecutar en la colección. los resultados pueden ser engañosos.
    • Yeh quise mencionar que en mi post que estas estadísticas probablemente iba a cambiar ahora con los navegadores mejorar, pero da una idea general.
    • No código postal, con fotos.
    • Creo que la única situación en la que la publicación de código como una imagen es aceptable es cuando el código es potencialmente peligroso y no debe ser copia-pega. En este caso, sin embargo, es bastante ridículo.
  12. 6

    Hay una solución más limpia:

    var srcArray = [1, 2, 3];
    var clonedArray = srcArray.length === 1 ? [srcArray[0]] : Array.apply(this, srcArray);

    La comprobación de la longitud es necesario, porque la Array constructor se comporta de forma diferente cuando se llama con exactamente un argumento.

    • Pero es el más rápido?
    • Más semántica que splice(), tal vez. Pero realmente, aplicar y esto es todo, pero intuitiva.
    • muestra el rendimiento más bajo en cromo- jsperf.com/new-array-vs-splice-vs-slice/113
    • Usted puede utilizar Array.of e ignorar la longitud: Array.of.apply(Array, array)
  13. 6

    Recordar .slice() no funciona para los dos-dimensiones de las matrices. Usted necesitará una función como esta:

    function copy(array) {
      return array.map(function(arr) {
        return arr.slice();
      });
    }
    • En Javascript no hay dos dimensiones de las matrices. No son sólo las matrices que contienen las matrices. Lo que estamos tratando de hacer es un copia profunda que no es necesario en la pregunta.
  14. 5

    Depende de la longitud de la matriz. Si la longitud del arreglo es <= 1,000,000, el slice y concat métodos de toma aproximadamente el mismo tiempo. Pero cuando te dan un rango más amplio, el concat método gana.

    Por ejemplo, prueba este código:

    var original_array = [];
    for(var i = 0; i < 10000000; i ++) {
        original_array.push( Math.floor(Math.random() * 1000000 + 1));
    }
    
    function a1() {
        var dup = [];
        var start = Date.now();
        dup = original_array.slice();
        var end = Date.now();
        console.log('slice method takes ' + (end - start) + ' ms');
    }
    
    function a2() {
        var dup = [];
        var start = Date.now();
        dup = original_array.concat([]);
        var end = Date.now();
        console.log('concat method takes ' + (end - start) + ' ms');
    }
    
    function a3() {
        var dup = [];
        var start = Date.now();
        for(var i = 0; i < original_array.length; i ++) {
            dup.push(original_array[i]);
        }
        var end = Date.now();
        console.log('for loop with push method takes ' + (end - start) + ' ms');
    }
    
    function a4() {
        var dup = [];
        var start = Date.now();
        for(var i = 0; i < original_array.length; i ++) {
            dup[i] = original_array[i];
        }
        var end = Date.now();
        console.log('for loop with = method takes ' + (end - start) + ' ms');
    }
    
    function a5() {
        var dup = new Array(original_array.length)
        var start = Date.now();
        for(var i = 0; i < original_array.length; i ++) {
            dup.push(original_array[i]);
        }
        var end = Date.now();
        console.log('for loop with = method and array constructor takes ' + (end - start) + ' ms');
    }
    
    a1();
    a2();
    a3();
    a4();
    a5();

    Si se establece la longitud de original_array a 1.000.000, el slice método y concat método de toma aproximadamente el mismo tiempo (3-4 ms, dependiendo de los números aleatorios).

    Si se establece la longitud de original_array 10000000, entonces el slice método toma más de 60 la ms y la concat método toma más de 20 ms.

    • dup.push está mal en a5, en lugar dup[i] = debe ser utilizado
  15. 4

    ECMAScript 2015 manera con el Spread operador:

    Ejemplos básicos:

    var copyOfOldArray = [...oldArray]
    var twoArraysBecomeOne = [...firstArray, ..seccondArray]

    Probar en el navegador de la consola:

    var oldArray = [1, 2, 3]
    var copyOfOldArray = [...oldArray]
    console.log(oldArray)
    console.log(copyOfOldArray)
    
    var firstArray = [5, 6, 7]
    var seccondArray = ["a", "b", "c"]
    var twoArraysBecomOne = [...firstArray, ...seccondArray]
    console.log(twoArraysBecomOne);

    Referencias

    • Probablemente la única cosa que es rápido con la propagación es a través de ella. Es muchísimo menos eficientes que otras formas de hacerlo.
    • Sírvanse proporcionar algunos enlaces acerca de su argumento.
  16. 2
            const arr = ['1', '2', '3'];
    
             //Old way
            const cloneArr = arr.slice();
    
            //ES6 way
            const cloneArrES6 = [...arr];
    
    //But problem with 3rd approach is that if you are using muti-dimensional 
     //array, then only first level is copied
    
            const nums = [
                  [1, 2], 
                  [10],
             ];
    
            const cloneNums = [...nums];
    
    //Let's change the first item in the first nested item in our cloned array.
    
            cloneNums[0][0] = '8';
    
            console.log(cloneNums);
               //[ [ '8', 2 ], [ 10 ], [ 300 ] ]
    
            //NOOooo, the original is also affected
            console.log(nums);
              //[ [ '8', 2 ], [ 10 ], [ 300 ] ]

    Así, con el fin de evitar estos escenarios a suceder, uso

            const arr = ['1', '2', '3'];
    
            const cloneArr = Array.from(arr);
    • Es válido señalar acerca de cómo cambiar cloneNums[0][0] en su ejemplo se propaga el cambio nums[0][0] – pero eso es porque el nums[0][0] es, efectivamente, un objeto cuya referencia se copian en cloneNums por la propagación del operador. Todo lo que es decir, este comportamiento no afecta el código en el que estamos copiando por valor (int, string, etc literales).
  17. 1

    De referencia de tiempo!

    JS:

    function log(data) {
      document.getElementById("log").textContent += data + "\n";
    }
    
    benchmark = (() => {
      time_function = function(ms, f, num) {
        var z = 0;
        var t = new Date().getTime();
        for (z = 0;
          ((new Date().getTime() - t) < ms); z++)
          f(num);
        return (z)
      }
    
      function clone1(arr) {
        return arr.slice(0);
      }
    
      function clone2(arr) {
        return [...arr]
      }
    
      function clone3(arr) {
        return [].concat(arr);
      }
    
      Array.prototype.clone = function() {
        return this.map(e => Array.isArray(e) ? e.clone() : e);
      };
    
      function clone4(arr) {
        return arr.clone();
      }
    
    
      function benchmark() {
        function compare(a, b) {
          if (a[1] > b[1]) {
            return -1;
          }
          if (a[1] < b[1]) {
            return 1;
          }
          return 0;
        }
    
        funcs = [clone1, clone2, clone3, clone4];
        results = [];
        funcs.forEach((ff) => {
          console.log("Benchmarking: " + ff.name);
          var s = time_function(2500, ff, Array(1024));
          results.push([ff, s]);
          console.log("Score: " + s);
    
        })
        return results.sort(compare);
      }
      return benchmark;
    })()
    log("Starting benchmark...\n");
    res = benchmark();
    
    console.log("Winner: " + res[0][0].name + " !!!");
    count = 1;
    res.forEach((r) => {
      log((count++) + ". " + r[0].name + " score: " + Math.floor(10000 * r[1] / res[0][1]) / 100 + ((count == 2) ? "% *winner*" : "% speed of winner.") + " (" + Math.round(r[1] * 100) / 100 + ")");
    });
    log("\nWinner code:\n");
    log(res[0][0].toString());

    HTML:

    <textarea rows="50" cols="80" style="font-size: 16; resize:none; border: none;" id="log"></textarea>

    El punto de referencia se ejecutará durante 10s desde hace clic en el botón.

    Mis resultados:

    Chrome (V8):

    1. clone1 score: 100% *winner* (4110764)
    2. clone3 score: 74.32% speed of winner. (3055225)
    3. clone2 score: 30.75% speed of winner. (1264182)
    4. clone4 score: 21.96% speed of winner. (902929)

    Firefox (Mono Araña Del Motor):

    1. clone1 score: 100% *winner* (8448353)
    2. clone3 score: 16.44% speed of winner. (1389241)
    3. clone4 score: 5.69% speed of winner. (481162)
    4. clone2 score: 2.27% speed of winner. (192433)

    Ganador código:

    function clone1(arr) {
        return arr.slice(0);
    }

    Ganador del motor:

    Mono Araña (Mozilla/Firefox)

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea