Foros del Web » Programando para Internet » Javascript »

Me conviene usar eval aca ?

Estas en el tema de Me conviene usar eval aca ? en el foro de Javascript en Foros del Web. Hola, estoy programando una clase en determinado momento debe evaluar una cierta cantidad de condiciones lógicas y ... que si todas estas condiciones son verdaderas ...

  #1 (permalink)  
Antiguo 18/04/2008, 10:37
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Me conviene usar eval aca ?

Hola, estoy programando una clase en determinado momento debe evaluar una cierta cantidad de condiciones lógicas y ... que si todas estas condiciones son verdaderas dispare una acción.

supongamos ...

Código:
var vectorCondicion = [];  // Array de condiciones

var condicion = true;
for (var = 0; i <= vectorCondicion i++) {
    if (!vectorCondicion[i]) {
        condicion = false;
        break;
    }
}
Primero definimos la variable condicion = true. Luego el buble evalúa todas las condiciones del array vectorCondicion ... en cuanto encuentra una condición falsa sale del bucle (con break) previamente definiendo condición a false.

Mi pregunta es si existe alguna manera de hacer este tipo de calculo lógico de una manera mas eficiente.

Había pensado en generar una cadena de texto y utilizar la función eval. Algo así ... (estoy improvisando, el error de sintaxis es inminente):

Código:
var cadenaCondicion = '';
var vectorCondicion = [];  // Array de condiciones

for (var i=0; i <= vectorCondicion.length; i ++)
    cadenaCondicion = cadenaCondicion + '  vectorCondicion [\'i\'] && ';

// Elimino la ultima cadena sobrante ' && '
cadenaCondicion = cadenaCondicion.substr (0, cadenaCondicion.length - 4);

// Finalmente evalúo
if (cadenaCondicion) ...

No se si se entiende la idea ... y si se entiende, alguien me puede decir cual de los dos procedimientos es mejor ?
Saludos y Gracias.
__________________
| Cabeza De Raton |
  #2 (permalink)  
Antiguo 18/04/2008, 12:22
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años
Puntos: 1284
Re: Me conviene usar eval aca ?

Hola Calisco, cuanto tiempo sin coincidir...:

Hay muchas posibilidades, te propongo una que acaba de ocurrirme:

En vez de true y false poner la cadena vacía por true y cualquier letra por false... entonces obtienes true si el join() de todos los elementos del array es la cadena vacía:

vector[i] = (true) ? "":"*";
vectorCierto = vector.join("").length == 0;

Supongo que mostrarán otras variantes...

Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #3 (permalink)  
Antiguo 18/04/2008, 15:51
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Re: Me conviene usar eval aca ?

Estoy a años luz de tener una buena concepción de la programación ... sobre todo JS.
Muy bueno el ejemplo ... sabes, estaba pensando en sumar las condiciones lógicos ... si son todas false la suma también lo sería. Se podría encarar de esa manera también, no ?
Sabes algún método para medir rendimiento, consumo de memoria, etc; de un script en JS ?
Saludos y gracias.
__________________
| Cabeza De Raton |
  #4 (permalink)  
Antiguo 18/04/2008, 16:34
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años
Puntos: 1284
Re: Me conviene usar eval aca ?

Hola:

Pues con los valores lógicos deberías pensar en la conjunción lógica... con que uno de los valores sea false es sufi... pero la implementación es más trabajosa... al menos hay que hacer un bucle.

Sobre el rendimiento, siempre es mejor usar primitivas del lenguaje, y los bucles suelen tener más penalización en el rendimiento...

Tratando de calcular el rendimiento, si no me equivoqué en nada, el código que te propuse tan solo tiene una primitiva o instrucción (y una comparación)

Con valores lógicos sería:
vale = true:
for (i = 0; i < vectorCondicion.length; i ++) vale = vale && vectorCondicion[i];

En ese caso la respuesta depende del tamaño del array...

Más o menos eso me ensañaron, pero la realidad es que hay primitivas que son más rápidas y eficientes que otras... tal vez las comparaciones y asignaciones sean las que mejor o más rápida respuesta tienen...

Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #5 (permalink)  
Antiguo 19/04/2008, 06:21
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Re: Me conviene usar eval aca ?

Gracias. Saludos.
__________________
| Cabeza De Raton |
  #6 (permalink)  
Antiguo 19/04/2008, 07:22
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Re: Me conviene usar eval aca ?

Cita:
Iniciado por caricatos Ver Mensaje
En vez de true y false poner la cadena vacía por true y cualquier letra por false... entonces obtienes true si el join() de todos los elementos del array es la cadena vacía:

vector[i] = (true) ? "":"*";
vectorCierto = vector.join("").length == 0;
caricatos estoy pensando en esta solución con eval() desde que he empezado a leer el post, y tu respuesta me ha inspirado en ello:

Código PHP:
var condiciones = new Array( truefalsetruetruetruefalse);
var 
todasTrue = eval("New Boolean( "+condiciones.join(" && ")+ ")"); 
Supongo que funcionaría, símplemente unimos todos los condicionantes con && y los convertimos en Boolean (por si acaso, no sé).


Y rendimiento, pues no lo sé. Habría que probar cuando condiciones.length se va hasta 10000 o así .


Saludos.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #7 (permalink)  
Antiguo 19/04/2008, 08:44
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años
Puntos: 1284
Re: Me conviene usar eval aca ?

Hola derkenuke , otra alternativa muy interesante y digna de estudiar.

La verdad es que cuando vi el título del mensaje la primera idea que tuve era más o menos así, pero mi intención era evitar el uso de eval... creo que todos los casos que conozco de uso de eval, puede sustituirse omitiéndolo, así que se gana en optimización en al menos "una primitiva"... claro que es una ganancia imperceptible, pero, al final en ambos casos se genera primero una cadena, y luego se hace una evaluación... creo que aún se puede mejorar más...

Por cierto, el new era en minúsculas ¡no!

Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #8 (permalink)  
Antiguo 19/04/2008, 09:07
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Re: Me conviene usar eval aca ?

Cita:
Iniciado por caricatos Ver Mensaje
Por cierto, el new era en minúsculas ¡no!

Jajaj Sí, el New era en minúsculas...


Otra idea que se me ocurre, es que como el array de condiciones va a contener siempre true o false, y el método toString() de un Boolean nos asegura que siempre devolverá "true" o "false", siempre se puede obtener el String que forma el array y mirar si existe "false":
Código PHP:
var condiciones = new Array( truefalsetruetruetruefalse);
var 
existeFalse condiciones.toString().indexOf("false") > -1
Creo que definitivamente esta forma es la más rápida. Otra cosa es si queremos evaluar elementos que no sean de tipo Boolean (cadenas vacías, números, elementos nulos...) ahí este método no sirve.


El tema del anterior eval se me ocurrió porque para calcular el mayor valor de un array de números siempre uso:
Código PHP:
var valorMaximo = eval(" Math.max("miArrayNumerico.join(",") +")" ); 
Así me ahorro los bucles y las variables auxiliares. Nunca he hecho una prueba de si rinde mejor eso u otra cosa.


Saludos.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #9 (permalink)  
Antiguo 19/04/2008, 09:28
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Re: Me conviene usar eval aca ?

Oye nada, que me ha venido la curiosidad de medir el rendimiento. 60 000 elementos aleatorios en el array y dos métodos de hallar el máximo: El eval y el de bucle.
Código PHP:
var miArrayNumerico = new Array(60000);
// relleno el array
for(var i=0elementos miArrayNumerico.lengthi<elementosi++)
    
miArrayNumerico[i] = Math.random()*elementos;

function 
maxConEval(arr) {
    return eval(
"Math.max("+arr.join(",")+")");
}
function 
maxConBucle(arr) {
    for(var 
i=0maximo=0i<arr.lengthi++ )
        if(
arr[i]>maximomaximo=arr[i];
    return 
maximo;
}


// inicio prueba maxConEval
var ini = new Date().getTime();
var 
$maxConEval maxConEval(miArrayNumerico);
var 
tardanza = (new Date().getTime())-ini;
document.write("Según maxConEval el máximo es "+$maxConEval+" y ha tardado en sacarlo "+tardanza+" ms.<br/>");

// inicio prueba maxConBucle
var ini = new Date().getTime();
var 
$maxConBucle maxConBucle(miArrayNumerico);
var 
tardanza = (new Date().getTime())-ini;
document.write("Según maxConBucle el máximo es "+$maxConBucle+" y ha tardado en sacarlo "+tardanza+" ms.<br/>"); 

Los resultados hablan por sí solos:
Cita:
Iniciado por FF2
Según maxConEval el máximo es 59999.26454998953 y ha tardado en sacarlo 3031 ms.
Según maxConBucle el máximo es 59999.26454998953 y ha tardado en sacarlo 219 ms.
Cita:
Iniciado por IE6
Según maxConEval el máximo es 59996.64244955615 y ha tardado en sacarlo 469 ms.
Según maxConBucle el máximo es 59996.64244955615 y ha tardado en sacarlo 63 ms.
Así que es más lento el eval, con diferencia.

Con booleanos pasará lo mismo.

Saludos.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #10 (permalink)  
Antiguo 19/04/2008, 09:46
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Re: Me conviene usar eval aca ?

Que bueno derke.
Saludos.
__________________
| Cabeza De Raton |
  #11 (permalink)  
Antiguo 19/04/2008, 09:49
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Re: Me conviene usar eval aca ?

Yo pensaba que la utilización de eval era mas eficiente; o es el Math.max quien ralentiza la función ?
__________________
| Cabeza De Raton |

Última edición por Calisco; 19/04/2008 a las 10:43
  #12 (permalink)  
Antiguo 19/04/2008, 09:57
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Re: Me conviene usar eval aca ?

Tomando el último elemento se podría ... pero modifica las posiciones del elemento del array, no ?
__________________
| Cabeza De Raton |
  #13 (permalink)  
Antiguo 19/04/2008, 11:08
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Re: Me conviene usar eval aca ?

¿Qué quieres decir con tomando el último elemento? ¿Usando pop()? Supongo que sería todavía más costoso por modificar los elementos del array en sí.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #14 (permalink)  
Antiguo 19/04/2008, 11:10
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Re: Me conviene usar eval aca ?

si, a eso me refería.
__________________
| Cabeza De Raton |
  #15 (permalink)  
Antiguo 19/04/2008, 11:22
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años
Puntos: 1284
Re: Me conviene usar eval aca ?

Hola:

Se está poniendo el tema más interesantes... por cierto, lo del máximo, tal vez usando la primitiva sort y pillando el último elemento...
miArray.sort()[miArray.length - 1]... o incluso pillar el primero pero antes hacer un reverse()...

Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #16 (permalink)  
Antiguo 19/04/2008, 12:29
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Re: Me conviene usar eval aca ?

Para los máximos igual abrimos otro tema y proponemos diferentes soluciones allí, que si no me enrollo y aquí estamos para hablar de boleanos. Habría que probar diferentes sistemas y hacer una prueba como la que he hecho antes.

Código PHP:
var condiciones = new Array(60000);
// relleno el array
for(var i=0elementos condiciones.lengthi<elementosi++)
    
condiciones[i] = new BooleanMath.round(Math.random()*1.5) );

function 
ejecutarPrueba(titulocodigo) {
    var 
ini = new Date().getTime();
    var 
resultado codigo();
    var 
tardanza = (new Date().getTime())-ini;
    
document.write("Según <b>"+titulo+"</b> el resultado es <b>"+resultado+"</b> y ha tardado en sacarlo "+tardanza+" ms.<br/>");
}


ejecutarPrueba"Con bucle y devolviendo false si hay false", function() {
        for(var 
i=0elementos condiciones.lengthi<elementosi++)
            if( 
condiciones[i] == false )
                return 
false;
        return 
true;
    } 
);

ejecutarPrueba"Con indexOf y mirando si existe \"false\" ", function() {
        return 
condiciones.toString().indexOf("false") > -1;
    }
);

/*
// Me da error: Too much recursion ¿?
ejecutarPrueba( "Con eval y juntando todo el array con &&", function() {
        return eval("new Boolean( "+condiciones.join(" && ")+ ")");
    }
);
*/

ejecutarPrueba("Con bucle y haciendo valorAcumulado = valorAcumulado && actual", function() {
        for(var 
i=0elementos condiciones.lengthvalorAcumulado truei<elementos && valorAcumulado==truei++)
            
valorAcumulado valorAcumulado && condiciones[i];
        return 
valorAcumulado;
    }
); 
Los resultados:
Cita:
Iniciado por IE6
Según Con bucle y devolviendo false si hay false el resultado es false y ha tardado en sacarlo 0 ms.
Según Con indexOf y mirando si existe "false" el resultado es true y ha tardado en sacarlo 328 ms.
Según Con bucle y haciendo valorAcumulado = valorAcumulado && actual el resultado es false y ha tardado en sacarlo 0 ms.
Cita:
Iniciado por FF2
Según Con bucle y devolviendo false si hay false el resultado es false y ha tardado en sacarlo 0 ms.
Según Con indexOf y mirando si existe "false" el resultado es true y ha tardado en sacarlo 516 ms.
Según Con bucle y haciendo valorAcumulado = valorAcumulado && actual el resultado es false y ha tardado en sacarlo 0 ms.
Bueno, salta a la vista que los resultados dependen también del array: Si tenemos 1000 elementos true y el último es false no habrá mucha diferencia. Pero si los tenemos muy mezclados, como en el ejemplo, y en cuanto encontremos un false paramos, la búsqueda se hace muy fácil.


En el caso general lo mejor es buscar uno a uno, y en cuanto encontremos un false parar. Esas son mis conclusiones.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #17 (permalink)  
Antiguo 19/04/2008, 14:37
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Re: Me conviene usar eval aca ?

Claro Caricatos, a eso me refería yo usando sort (). Interesante tema. Para mi es muy importante saacarle el jugo a los scripts. Después la sigo ... saludos.
__________________
| Cabeza De Raton |
  #18 (permalink)  
Antiguo 19/04/2008, 16:27
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años
Puntos: 1284
Re: Me conviene usar eval aca ?

Hola:

Añado otras pruebas (intentando respetar las anteriores):

Código:
ejecutarPrueba("Con sort() de valores lógicos, tomando el primero", function() {
        return condiciones.sort()[0];
    }
);  

ejecutarPrueba("Con una cadena, concatenando un asterisco por cada false", function() {

        for(var i = 0, elementos = condiciones.length, str = ""; i < elementos; str += (condiciones[i]) ? "": "*", i++)
        return str != "";
    }
);  

ejecutarPrueba("Creando un array con cadenas de 0 y 1 caracter, según condición", function() {
        
        for(var i = 0, elementos = condiciones.length, str = new Array(); i < elementos; str[i] = (condiciones[i]) ? "" : "*", i++)
        return str.join("") != "";
    }
);
Los resultados (junto a los que devuelve mi máquina con las otras pruebas):

Código:
Según Con bucle y devolviendo false si hay false el resultado es false y ha tardado en sacarlo 0 ms.
Según Con indexOf y mirando si existe "false" el resultado es true y ha tardado en sacarlo 265 ms.
Según Con bucle y haciendo valorAcumulado = valorAcumulado && actual el resultado es false y ha tardado en sacarlo 0 ms.
Según Con sort() de valores lógicos, tomando el primero el resultado es false y ha tardado en sacarlo 735 ms.
Según Con una cadena, concatenando un asterisco por cada false el resultado es false y ha tardado en sacarlo 0 ms.
Según Creando un array con cadenas de 0 y 1 caracter, según condición el resultado es false y ha tardado en sacarlo 0 ms.
Intentando interpretar los resultados, vemos que la primitiva sort() de los arrays es lo que más tarda, ya que devolver luego el primer elemento es trivial... y lo que me ha gustado es que creando un array de cadenas ("" y "*") es también de lo más rápido...

Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #19 (permalink)  
Antiguo 21/04/2008, 11:33
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Re: Me conviene usar eval aca ?

Bien, he terminado de acomodar el código generado en este post y puse un ejemplo onLine. La verdad que el tiempo invertido ha valido la pena. Antes, un par de aclaraciones. Por un lado he definido tres modos de prueba: Random, todos True y Todos False. El título lo dice todo. Por otro, agregué una función más que utiliza el método contains() de mooTools.

La función resulta sencilla:
Código PHP:
ejecutarPrueba("Utilizando \'contains\' de mootools buscando un elemento \'false\'", function() {
        return 
condiciones.contains ('false');
    }
); 
El código copiado del fuente del framework del método extendido del objeto array de mootools es el siguiente:
Código PHP:
    contains: function(itemfrom){
        return 
this.indexOf(itemfrom) != -1;
    }, 

Estos son los links de testeo:

Modo Random.
Modo Todos True.
Modo Todos False.

Las pruebas son sometidas, como ha definido Derke, en un array de 60000 elementos.
De los datos obtenidos saco como conclusión que Con una cadena, concatenando un asterisco por cada false y Creando un array con cadenas de 0 y 1 caracter, según condición resultan ser las más eficientes ya que en mi PC (Linux + FF2) los tiempos son todos 0ms en los tres modos.
Con bucle y devolviendo false si hay false y Con bucle y haciendo valorAcumulado = valorAcumulado && actual funcionan bien en todos los casos menos en el modo Todos True.
Los tiempos del método contains() de mootools son mas o menos los mismos para los distintos modos. De todas formas, este método es más abarcativo. Este es link de la doc.
Los otros pierden por varios caballos.

Alguien puede poner los valores bajo IE ? (puaj !).

Queda algo mas ?. Saludos.
__________________
| Cabeza De Raton |
  #20 (permalink)  
Antiguo 21/04/2008, 12:41
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Re: Me conviene usar eval aca ?

Bueno ... no me aguanté y le pedí a mi jermu que lo probara en IE6. Esta es la captura:

Adío.
__________________
| Cabeza De Raton |
  #21 (permalink)  
Antiguo 21/04/2008, 12:51
Avatar de MaBoRaK  
Fecha de Ingreso: abril-2003
Ubicación: La Paz - Bolivia
Mensajes: 2.003
Antigüedad: 21 años
Puntos: 35
Re: Me conviene usar eval aca ?

loading...........

No se ustedes... pero para mi es mejor hacerlo así

Código PHP:
Array.prototype.valid=function(valid)
{
    
valid valid || false;
    for(var 
i=0;i<this.length;i++)
    {
        if(
this[i]!==valid){return false;}
    }
    return 
true;
}
//llenamos el array
var a=[];
for(var 
i=0;i<59999;i++)
{
    
a.push(true);
}
//hasta aca tenemos un Array de validos, osea todos true
a.push(false); //ponemos un ultimo valor false, debemos llegar hasta ahi en el recorrido
//ya que si usamos un valor random, puede darnos false en el primer valor de la matriz y suelta 0
//asi que.. como digo, dejes todo en true y al final false. Esto se tomaria como CASO EXTREMO
var ini = new Date().getTime(); //iniciamos test
var a.valid(true); //validamos que si todos son true, devuelva true en g y si alguno difiere,,, pues devuelve false.
var tardanza = (new Date().getTime())-ini//prueba final
alert(tardanza
El test no pasa de 50 ms. se mantiene entre 48 y 50.

La forma de hacerlo en cadena (indexOf) ... consume mucha memoria, asi que la descartamos

Cita:
Según Con bucle y haciendo valorAcumulado = valorAcumulado && actual el resultado es false y ha tardado en sacarlo 0 ms.
<-- es igual que hacerlo con bucle ya que SE ACCEDE AL VALOR DEL ARRAY.

Entonces la solucion que mejoraría esto, sería el tener que comprobar(todos los elementos del array) si alguno de los valores es diferente a true. Asi que .. no hay forma de hacer esto y terminamos siempre leyendo el valor siguiente del array.

Talvez ya dijeron esta idea... pero algo que tambien ayudaría muchisimo es hacer comprobaciones por ambos lados, principio y final.

Código PHP:
Array.prototype.valid=function(valid)
{
    
valid valid || false;
    for(var 
i=0,j=1;i<this.length;i++)
    {
        var 
this.length-j;
        
//console.info("i="+i+":"+this[i]);
        //console.info("o="+o+":"+this[o]);
        
if(this[i]!=valid || this[o]!=valid)
        {
            return 
false;
        }
        else if(
i>o)
        {
            return 
true;
        }
        
j+=1;
    }
    return 
true;
};
var 
a=[];
for(var 
i=0;i<60000;i++)
{
    
a.push(true);
}

//ponemos un valor false en el punto 50000
a[50000]=false;
var 
ini = new Date().getTime();
var 
a.valid(true);
var 
tardanza = (new Date().getTime())-ini;
alert(tardanza
Con este script el retardo hasta llegar a comprobar la posición 50000 (ahi pusimos el false) se reduce a 17ms, mientras que con la forma de avanzar elemento tras elemento tarda 37ms

Ahora bien, otro método sería hacer búsquedas en la matriz a partir de un valor random saltando por la matriz pero que NO DEBE SALTAR EN EL MISMO valor 2 veces.
Ahora bien tambien sería bueno separar la busqueda en la matriz en diferentes procesos, pero la cantidad de procesos no debe superar el 1/4 del total de los elementos.

Y como ven.. se pueden hacer muchas cosas mas :D

connection closed.
__________________

Maborak Technologies

Última edición por MaBoRaK; 21/04/2008 a las 15:50
  #22 (permalink)  
Antiguo 21/04/2008, 13:29
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Re: Me conviene usar eval aca ?

Acabo de agregar dos modos mas de prueba; luego de leer el post de MaBoRak. Uno es Todos True + 1 False y el otro es Todos False + 1 True. Entonces tenemos 5 modos:

Random.
Todos True.
Todos False.
Todos True + 1 False.
Todos False + 1 True.

O estoy haciendo mal, o siguen perdurando como funciones de rendimiento óptimo las que ha diseñado Caricatos. La que has hecho MaboRak no la he implementado; pero óptimo es 0ms. Tal vez podríamos agregar un elemento dentro del array en una posición aleatoria ...
Saludos.
__________________
| Cabeza De Raton |
  #23 (permalink)  
Antiguo 21/04/2008, 13:55
Avatar de MaBoRaK  
Fecha de Ingreso: abril-2003
Ubicación: La Paz - Bolivia
Mensajes: 2.003
Antigüedad: 21 años
Puntos: 35
Re: Me conviene usar eval aca ?

loading.............

Ok, te lo pongo para hacer las pruebas :D
Con valores aleatorios sería asi.

Código PHP:
Array.prototype.valid=function(valid)
{
    
valid valid || false;
    for(var 
i=0,j=1;i<this.length;i++)
    {
        var 
this.length-j;
        
//console.info("i="+i+":"+this[i]);
        //console.info("o="+o+":"+this[o]);
        
if(this[i]!=valid || this[o]!=valid)
        {
            return 
false;
        }
        else if(
i>o)
        {
            return 
true;
        }
        
j+=1;
    }
    return 
true;
};
//creamos array
var a=[];
for(var 
i=0;i<60000;i++)
{
    
a.push(new BooleanMath.round(Math.random()*1.5) ););
}
var 
ini = new Date().getTime();
var 
a.valid(true);
var 
tardanza = (new Date().getTime())-ini;
alert(tardanza
connection closed.
__________________

Maborak Technologies

Última edición por MaBoRaK; 21/04/2008 a las 15:50
  #24 (permalink)  
Antiguo 21/04/2008, 14:34
Avatar de MaBoRaK  
Fecha de Ingreso: abril-2003
Ubicación: La Paz - Bolivia
Mensajes: 2.003
Antigüedad: 21 años
Puntos: 35
Re: Me conviene usar eval aca ?

loading............

Bueno yo hice la prueba :D con 200000 elementos :D. Por favor use protector de ojos para probar jejejejeje.

http://maborak.com/incubator/arr.html?1
http://maborak.com/incubator/arr.html?2
http://maborak.com/incubator/arr.html?3
http://maborak.com/incubator/arr.html?4

A proposito CALISCO copiaste mal los codigos por eso los scripts de caricatos devolvian 0 o 1 ms

Este es el archivo final
Código PHP:
<html>
    <
head>
    <
script type="text/javascript">
/**
 * @author xifox
 */
Array.prototype.valid=function(valid)
{
    
valid valid || false;
    for(var 
i=0,j=1;i<this.length;i++)
    {
        var 
this.length-j;
        
//console.info("i="+i+":"+this[i]);
        //console.info("o="+o+":"+this[o]);
        
if(this[i]!=valid || this[o]!=valid)
        {
            return 
false;
        }
        else if(
i>o)
        {
            return 
true;
        }
        
j+=1;
    }
    return 
true;
};
modo = (document.location).toString().split ('?')[1].substr ((document.location).toString().split ('?')[1].length 11);
txtModo = ['Random ''Todos True''Todos False''Todos True + 1 False''Todos False + 1 True']

var 
condiciones = new Array(200000);

document.write ('<h3>Modo ' txtModo[modo] + '</h3>');
// relleno el array
for (var 0elementos condiciones.lengthelementosi++) {
    switch (
modo) {
        case 
'0':
        
condiciones[i] = new Boolean(Math.round(Math.random() * 1.5));
        break;
        
        case 
'1':
        
condiciones[i] = new Boolean (true);
        break;
        
        case 
'2':
        
condiciones[i] = new Boolean (false);
        break;

        case 
'3':
        
condiciones[i] = new Boolean (true);
        break;

        case 
'4':
        
condiciones[i] = new Boolean (false);
        break;
    }
}

    switch (
modo) {
        case 
'3':
        
condiciones.push (new Boolean (false));
        break;

        case 
'4':
        
condiciones.push (new Boolean (true));
        break;
    }

//console.log (modo, condiciones);

function ejecutarPrueba(titulocodigo) {
    var 
ini = new Date().getTime();
    var 
resultado codigo();
    
    var 
tardanza = (new Date().getTime())-ini;
    
document.write("<p>Segun <b>"+titulo+"</b> el resultado es <b>"+resultado+"</b> y ha tardado en sacarlo <span id=\"tardanza\">"+tardanza+" ms</span>.</p>");
}

ejecutarPrueba(" maborak con doble busqueda devuelve false si encuentra un false en el Array:", function() {
        return 
condiciones.valid(true);
    }
);

ejecutarPrueba"Con bucle y devolviendo false si hay false", function() {
        for(var 
i=0elementos condiciones.lengthi<elementosi++)
            if( 
condiciones[i] == false )
                return 
false;
        return 
true;
    } 
);

ejecutarPrueba"Con indexOf y mirando si existe \"false\" ", function() {
        return 
condiciones.toString().indexOf("false") > -1;
    }
);

/*
// Me da error: Too much recursion Â¿?
ejecutarPrueba( "Con eval y juntando todo el array con &&", function() {
        return eval("new Boolean( "+condiciones.join(" && ")+ ")");
    }
);
*/

ejecutarPrueba("Con bucle y haciendo valorAcumulado = valorAcumulado && actual", function() {
        for(var 
i=0elementos condiciones.lengthvalorAcumulado truei<elementos && valorAcumulado==truei++)
            
valorAcumulado valorAcumulado && condiciones[i];
        return 
valorAcumulado;
    }
); 
ejecutarPrueba("Con sort() de valores lógicos, tomando el primero", function() {
        return 
condiciones.sort()[0];
    }
);  

ejecutarPrueba("Con una cadena, concatenando un asterisco por cada false", function() {

        for(var 
0elementos condiciones.lengthstr ""elementosstr += (condiciones[i]) ? """*"i++)
        {}
        return 
str != "";
    }
);  

ejecutarPrueba("Creando un array con cadenas de 0 y 1 caracter, según condición", function() {
        
        for(var 
0elementos condiciones.lengthstr = new Array(); elementosstr[i] = (condiciones[i]) ? "" "*"i++)
        {}
        return 
str.join("") != "";
    }
);

</script>
    </head>
    <body></body></html> 
connection closed.
__________________

Maborak Technologies

Última edición por MaBoRaK; 21/04/2008 a las 15:49
  #25 (permalink)  
Antiguo 21/04/2008, 15:29
Avatar de MaBoRaK  
Fecha de Ingreso: abril-2003
Ubicación: La Paz - Bolivia
Mensajes: 2.003
Antigüedad: 21 años
Puntos: 35
Re: Me conviene usar eval aca ?

loading...........

PD:
new Boolean(true)==true <-- es true
pero
new Boolean(true)===true <-- es FALSE

connection closed.
__________________

Maborak Technologies
  #26 (permalink)  
Antiguo 21/04/2008, 16:16
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Re: Me conviene usar eval aca ?

Bueno bueno como se está poniendo el hilo...

Cita:
Iniciado por MaBoRaK Ver Mensaje
loading...........

PD:
new Boolean(true)==true <-- es true
pero
new Boolean(true)===true <-- es FALSE

connection closed.
Muy buen aporte MaBoRaK, no tenía ni idea de que eso pasara. La verdad, no me lo esperaba.

Algunos resultados más
Código PHP:
new Boolean(true) === true;                    //    false
new Boolean(true) === new Boolean(true);    //    false
new Number(7) === 7;                        //    false
new Number(7) === new Number(7);            //    false
new String("hola") === "hola";                //    false
!!new Boolean(true) === true;                //    true
!new Boolean(true) === !new Boolean(true);    //    true
true === eval(new Boolean(true));            //    false
true === eval("new Boolean(true)");            //    false    
true === eval("new Boolean("+true+")");        //    false
true === eval("!!new Boolean("+true+")");    //    true    
typeof true;                                //    boolean
typeof new Boolean(true);                    //    object
typeof !!new Boolean(true);                    //    boolean 
El operador new crea un objeto, y los objetos sólo dan igual a otros objetos no si son iguales, sino si son el mismo objeto.

Ni siquiera me lo habría parado a pensar...



Bueno, seguimos investigando con los métodos óptimos...
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #27 (permalink)  
Antiguo 21/04/2008, 16:25
Avatar de MaBoRaK  
Fecha de Ingreso: abril-2003
Ubicación: La Paz - Bolivia
Mensajes: 2.003
Antigüedad: 21 años
Puntos: 35
Re: Me conviene usar eval aca ?

loading..........


Me di cuenta de eso al comparar las funciones que exponemos aca.. siempre me salí false y yo "WTF?" y ahi me puse a poner typeof de new Boolean y SORPRISE!!!, es por eso que siempre trato de usar el operador new para definir variables y lo hago asi.

var a = []; <-- array
var b = {}; <-- objeto literal
var c = true; <- boolean
var d = 1; <-- entero

etc etc-


connection closed.
__________________

Maborak Technologies
  #28 (permalink)  
Antiguo 22/04/2008, 04:55
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Re: Me conviene usar eval aca ?

es verdad MaBoRaK, no me di cuenta de dejas vacío el bucle.
Saludos.
__________________
| Cabeza De Raton |
  #29 (permalink)  
Antiguo 22/04/2008, 07:03
Avatar de Calisco  
Fecha de Ingreso: marzo-2004
Ubicación: Neuquen
Mensajes: 732
Antigüedad: 20 años, 1 mes
Puntos: 4
Re: Me conviene usar eval aca ?

Me puse a jugar un poco más, ningún aporte de programación ... solo agregué la función de MaRoBaK y dos nuevos modos de prueba: Todos True + 1 False Aleatorio y Todos False + 1 True Aleatorio.
También me puse a jugar con google charts, nunca lo había hecho; interesante. Además agregué una barra de navegación sencilla al final de la página.

Link de Pruebas
http://xifox.net/pruebas/array-booleans/?0

La función contains () de mootools, que utiliza indexOf resulta ser la más regular, superando en dos test al script de MaRoBaK, quien en todas los demás ha resultado ser la mas eficiente llegando llegando al valor óptimo.
Me quedó picando lo del consumo de memoria. Como lo podemos medir ?
__________________
| Cabeza De Raton |
  #30 (permalink)  
Antiguo 22/04/2008, 08:05
Avatar de MaBoRaK  
Fecha de Ingreso: abril-2003
Ubicación: La Paz - Bolivia
Mensajes: 2.003
Antigüedad: 21 años
Puntos: 35
Re: Me conviene usar eval aca ?

loading..........

No entiendo porque indexOf es mas rápido... ya que la implementación de indexOf es un bucle que se detiene si encuentra el valor.

Código PHP:
 indexOf: function(object) {
    for (var 
0length this.lengthlengthi++)
      if (
this[i] == object) return i;
    return -
1;
  }, 
bueno, al menos así lo implementa prototype pero ya mootools lo usa como nativo.


connection closed.
__________________

Maborak Technologies
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 2 personas




La zona horaria es GMT -6. Ahora son las 23:23.