Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 13-06-2011
JerS JerS is offline
Miembro
 
Registrado: may 2005
Ubicación: Venezuela
Posts: 254
Poder: 19
JerS Va por buen camino
Que es mas Rapido While,For,Repeat

Buenas amigos estoy haciendo una aplicación en Delphi 7 y necesito que sea lo mas rápida y que consuma lo mínimo en recursos,voy hacer varios ciclos y quisiera saber cual me recomiendan entre el WHILE,REPEAT y FOR gracias.
__________________
La vida es un simple pero complejo If

J=rS
Responder Con Cita
  #2  
Antiguo 13-06-2011
pcicom pcicom is offline
Miembro
 
Registrado: may 2003
Ubicación: MONTERREY MEXICO
Posts: 253
Poder: 21
pcicom Va por buen camino
Eso va a depender de la logica de tu programación.

Si conoces el numero de CICLOS entonces sera un FOR

De igual manera el WHILE y REPEAT dependera de como validar la continuacion del CICLO al INICIO o al FINALIZAR..

Mucho dependera de ti, ya que en ocaciones puedes hacer menos ciclos repitiendo varias veces parte del codigo en los mismos..

Por ejemplo.
Suponiendo que vas a llenar un array con 1000 registros, una forma de optimiarlo seria.

FOR i:=1 to 200 do
begin
vararray[i] := i;
vararray[i+200] := i+200;
vararray[i+400] := i+400;
vararray[i+600] := i+600;
vararray[i+800] := i+800;
end;


EN LUGAR DE

FOR i:=1 to 1000 do
begin
vararray[i] := i;
end;


Si checas en este CASO hacer 200 CICLOS en lugar de 1000..


SALUDOS... al final de cuentas todo depende de la LOGICA que al final de cuentas mientras obtengas resultados y que funcione dependera completamente de ti.
__________________
Poco ha de saber el que no pregunta.. Yo por eso soy un pregunton
Responder Con Cita
  #3  
Antiguo 13-06-2011
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.040
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Por supuesto, depende de muchos factores.
Responder Con Cita
  #4  
Antiguo 14-06-2011
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Hola JerS,
Para la máquina yo diría que le es indiferente. De todas formas, con cualquiera de ellos todo se reduce a lo mismo o muy parecido: intrucciones de salto o brinco.
Es decir, el compilador traducirá el fin de ciclo como una instrucción de tipo: si se cumple la condición te sales... y esto está ya altamente optimizado y se podría asumir (y asume) que consumirá lo mismo aunque se tratase de un while, un for o un repeat.

Como te han indicado los compañeros, el uso de estos ciclos dependerá de la naturaleza del problema. Lo que deba hacerse dentro es realmente lo que dará el peso real al problema.

Lo que puedes hacer, para tener una idea de la complejidad de tu algoritmo y de lo rápido y eficiente que podría ser es calcular la complejidad computacional (en notación O) como la complejidad ciclomática V(G).

La primera te dará una idea de lo rápido que podría hacer, y del "tiempo" que podría demorarse. Mientras que la segunda te dará una idea de lo complejo que es el algoritmo y de la cantidad de caminos y casos de prueba a aplicar para evaluarlo totalmente.

El ejemplo de pcicom es un clásico. Si tuviéramos que calcular la complejidad computacional fácilmente comprobaremos que es T(n/5) mientras que su contraparte es T(n). De todas formas, ambos tienen por asíntota una complejidad O(n). ¿Eso quiere decir que ambos se harán en el mismo tiempo? No... solamente es que el primero puede asumir una constante c 5 veces menor que el "original"... Esto se traduce a que el primer algoritmo puede recibir un vector de tamaño 5 veces mayor que el original para estar en las mismas condiciones del original.
Es decir que el algoritmo modificado "crece" 5 veces más lento, con lo que puede aprovecharse para más hacer operaciones.

Por ejemplo: si en vez de esos 1000 fueran 2000, con el primero sólo necesitaríamos 400 pasadas. Para igualar a las 2000 instrucciones del original... se necesita un vector de 10000.

Te aconsejo una lectura a libros sobre estructuras de datos y algoritmos. Allí encontrarás explicado el tema de la complejidad computacional.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #5  
Antiguo 14-06-2011
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Delphius Ver Mensaje
¿Eso quiere decir que ambos se harán en el mismo tiempo?
Pues yo creo que sí que se ejecutarán en el mismo tiempo. Cada vuelta del ciclo de cinco instrucciones se ejecutará cinco veces más lento que una vuelta del ciclo de una instrucción, con lo cual, realmente no se gana nada.

// Saludos
Responder Con Cita
  #6  
Antiguo 14-06-2011
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
caso for i := 0 to 1000
Código:
1 inicializar i=0
2 inicializar limite=1000
3   hacer algo
4 incrementar i
5 ver si i > limite
6 verdadero saltar a 3
Pasos 3 se ejecuta 1000 veces
Pasos 4 se ejecuta 1000 veces
pasos 5 se ejecuta 1000 veces
pasos 6 se ejecuta 1000 veces


caso for i := 0 to 200
Código:
1 inicializar i=0
2 inicializar limite=200
3   hacer algo
4   hacer algo
5   hacer algo
6   hacer algo
7   hacer algo
8 incrementar i
9 ver si i > limite
10 verdadero saltar a 3
Pasos 3 a 7 se ejecuta 1000 veces
pasos 8 se ejecuta 200 veces
pasos 9 se ejecuta 200 veces
pasos 10 se ejecuta 200 veces

Conclusión: En el caso de hacer un for, la parte final (incrementar, comporbar, saltar) se ejecuta tantas veces como el for.
La parte de dentro (hacer algo) siempre se ejecuta 1000 veces
caso 1 = 1000+100+1000+1000+1000 = 5000
caso 2 = 200+1000+200+200+200 = 1800
Responder Con Cita
  #7  
Antiguo 14-06-2011
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 22
Crandel Va por buen camino
Según creo el ciclo for es el mas rápido de todos.

Esto se debe a que la condición de salida ya esta prefijada antes de iniciarse, lo que permite al compilador realizar optimizaciones utilizando registros internos del procesador para el contador y la condición de salida (en realidad deberiamos analizar el assembler generado en los diferentes casos). En el ciclo for la condición de salida no puede ser modificada.

Por ejemplo:

Código Delphi [-]
var
 i, b, c: integer;
begin
  b := 10;
  c := 0;
  for i:=1 to b do
  begin
    b := 5;
    c := c +1;
  end;
  // aca c vale 10
end;

Este ciclo se ejecuto 10 veces y no 5.

Igualmente la diferencia no creo que sea apreciable y lo mas probable es que termines perdiendo mucho mas tiempo en otras partes de tu codigo o simplemente por tener un servicio innecesario corriendo en la misma maquina.
__________________
[Crandel]
Responder Con Cita
  #8  
Antiguo 14-06-2011
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por roman Ver Mensaje
Pues yo creo que sí que se ejecutarán en el mismo tiempo. Cada vuelta del ciclo de cinco instrucciones se ejecutará cinco veces más lento que una vuelta del ciclo de una instrucción, con lo cual, realmente no se gana nada.

// Saludos
Pues allí está el dilema y quizá una de las confusiones y errores cuando se habla de complejidad computacional. Por algo yo he dicho "tiempo" entre comillas. En realidad lo que indica la complejidad computacional es la tasa de crecimiento y la cantidad de operaciones involucradas.
El tiempo está dado por diversos factores, mayormente externos, y es lo que al final se simboliza con una constante, por lo general simbolizada por c.

Cuando comento la diferencia entre T(n) y T(n/5) estoy diciendo simplemente que el segundo crece 5 veces más lento. Por lo cual le permite recibir una entrada mayor al mismo costo. Para igualar las condiciones de T(n) la entrada que necesita debe ser 5 veces mayor. Si ambos algoritmos se prueban en un mismo equipo, con las mismas condiciones iniciales, etc. se tiene c * T(n) y c * T(n/5). Allí claramente se ve que el segundo caso es preferible al primero.

Pero en vista a a que tanto T(n) y T(n/5) tienen el mismo órden, directamente se habla en términos de asíntota: O(n), y luego las constantes c se "ajustan". Para el caso de T(n/5) la constante c es en realidad c/5.

¿Me explico?

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #9  
Antiguo 14-06-2011
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Algunos compiladores (como GCC y FPC, por ejemplo, y creo que algunas versiones de Delphi también) son capaces de hacer optimizaciones al estilo de lo explicado por duilioisola, lo que se denomina unroll loops.

Por otro lado, también depende de la longitud del código que ejecuta el bucle, así como la cantidad de los datos que manipula. Esto es importante sobre todo con los microprocesadores modernos ya que disponen de cachés internas que pueden acelerar considerablemente el acceso a los datos si se mantienen dentro de un cierto intervalo, así como circuitos de "predicción" que pueden acelerar la ejecución de algunas partes.

También depende del tipo de datos que van a comprobarse a la hora de establecer el final del bucle. Con FOR esto es fácil, ya que siempre debe ser un tipo ordinal (INTEGER, BYTE, LONGINT, etc.), siempre se incrementa o decrementa la variable "contadora" en una unidad, y siempre es una variable local, por lo que el compilador puede hacer multitud de optimizaciones que no podría en el caso de un bucle WHILE con parámetros en punto flotante, por ejemplo. Sin embargo, si el WHILE utiliza también ordinales pues es posible que sí pueda hacer algunas de las optimizaciones, aunque no todas, y por otro lado un bucle WHILE o REPEAT no tiene porqué modificar siempre el contenido de las variables implicadas en la condición final.

Otro detalle es que, por lo que sé, los bucles FOR sólo calculan las expresiones de la condición una vez, mientras que los bucles WHILE y REPEAT calculan estas expresiones cada vez que se repite el bucle (salvo si el resultado de la expresión se considera constante). Es decir:
Código Delphi [-]
  FOR Posicion := 1 TO Length (UnaVariableConTexto) DO ...

  Posicion := 1;
  WHILE Posicion <= Length (UnaVariableConTexto) DO ...
En el caso del FOR la longitud de "UnaVariableConTexto" se calculará una sola vez justo antes de iniciar el bucle, mientras que en el WHILE esta longitud se calcula cada vez que se hace la comprobación. Esto también afectaría dramáticamente al rendimiento del bucle.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #10  
Antiguo 14-06-2011
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Delphius Ver Mensaje
Cuando comento la diferencia entre T(n) y T(n/5) estoy diciendo simplemente que el segundo crece 5 veces más lento.
Desde aquí está el error. En todo caso, esta diferencia que supones es sólamente para el número de vueltas, más no para el costo total del ciclo.

// Saludos
Responder Con Cita
  #11  
Antiguo 14-06-2011
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Roman me parece que no nos entendemos.
Si suponemos que cada una de las instrucciones dentro del ciclo son triviales, todas tienen un O(1). Y el costo total de éstas, no es O(5). En el cálculo de complejidad computacional se toma siempre aquel de mayor orden, que es el que más incide y afecta. Como todas son O(1), un Max( O(1), O(1), O(1), O(1), O(1) ) simplemente dará O(1). Luego, éste se multiplica por el del for, que es justamente en el caso del algoritmo "quebrado", n/5. Para este algoritmo sigue siendo determinante en realidad las pasadas.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #12  
Antiguo 14-06-2011
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
A no ser que un JMP sea sustancialmente más lento que un MOV, creo que no aplica tu cálculo de complejidad.

// Saludos
Responder Con Cita
  #13  
Antiguo 14-06-2011
JerS JerS is offline
Miembro
 
Registrado: may 2005
Ubicación: Venezuela
Posts: 254
Poder: 19
JerS Va por buen camino
Muchas gracias por todos sus comentarios! hasta he desatado un buen foro con relación a los ciclos, la diferencia creo que seria minima y en mi caso lo que necesito es recorrer un Recordset de ADO o un Query de Zeos. y creo que sea cual sea el ciclo utilizado el consumo de recurso y el tiempo empleado es el mismo o con diferencias minimas
__________________
La vida es un simple pero complejo If

J=rS
Responder Con Cita
  #14  
Antiguo 14-06-2011
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.040
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Pues recorrer un dataset no tiene nada que ver con todo lo que se ha comentado aquí
Responder Con Cita
  #15  
Antiguo 14-06-2011
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por roman Ver Mensaje
A no ser que un JMP sea sustancialmente más lento que un MOV, creo que no aplica tu cálculo de complejidad.

// Saludos
Pues no entiendo a que apuntas.
¿Puedes desarrollar más en detalles tu idea?

Por mi parte sigo defendiendo que el algoritmo presentado, siendo n = 1000 y su contraparte del for i := 1 to 200 tienen T(n) y T(n/5) y una O(n) con diferentes constantes: c y c/5 respetivamente. Ahora si se ha cambiado la teoría de la complejidad computacional que me lo diga porque estoy más que seguro que estoy en lo cierto.

O si quieres ofrezco un caso al que me enfrenté hace unas semanas, para que lo estudiemos y determinemos cual de mis dos algoritmos que elaboré es más rápido o conveniente.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #16  
Antiguo 15-06-2011
JerS JerS is offline
Miembro
 
Registrado: may 2005
Ubicación: Venezuela
Posts: 254
Poder: 19
JerS Va por buen camino
Simplemente tengo una consulta donde me traigo un conjunto de cedulas y con esta cedula 1 a 1 tengo que ir preguntando en otras tablas donde busco por fechas 1 a 1 estoy usando un doble ciclo de la siguiente manera

Código Delphi [-]
While Not ZQuery1.EOF Do // en este query recorro las cedulas 1 a 1
.....

While Not ZQuery2.EOF Do //en este recorro con cada cedula en un rango de fecha 1 a 1 Ejm: 2011-05-01 hasta 2011-05-31
...
...
..
ZQuery2.next;
.....
....
ZQuery1.Next;
[/delphi]
__________________
La vida es un simple pero complejo If

J=rS
Responder Con Cita
  #17  
Antiguo 16-06-2011
Avatar de courtois
courtois courtois is offline
Miembro
 
Registrado: abr 2006
Ubicación: Mexico DF
Posts: 200
Poder: 19
courtois Va por buen camino
y por que no usas sql en vez de ciclos?
Responder Con Cita
  #18  
Antiguo 16-06-2011
JerS JerS is offline
Miembro
 
Registrado: may 2005
Ubicación: Venezuela
Posts: 254
Poder: 19
JerS Va por buen camino
Es complejo utilizarlo en SQL porque tengo que comparar muchas cosas
__________________
La vida es un simple pero complejo If

J=rS
Responder Con Cita
  #19  
Antiguo 16-06-2011
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 22
Crandel Va por buen camino
como suponía en un principio estas intentando limpiar sobre el piso limpio cuando tienes un basural a tu costado.

Todo el proceso de traer registros y filtrarlos en tu propio programa es muy pesado y potencialmente peligroso si tus tablas tienden a crecer.

Las bases de datos ya implementan optimización en la búsqueda y filtrado de los datos y por mas que logres velocidades similares el solo hecho de no transferir datos incensarios ya implica un gran ahorro.

Como te recomendó courtois, centrate en generar una buena instrucción SQL.
__________________
[Crandel]
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Ayudenme Rapido, Rapido omarys Varios 6 04-06-2011 09:45:34
Interrumpir un ciclo Repeat - Until FGarcia Varios 10 07-01-2009 00:06:10
¿Qué es más rapido? jcarteagaf Humor 3 05-07-2008 02:48:58
Duda sobre variable en un Bucle Repeat gerupc Varios 9 21-07-2007 02:44:34
...rapido de mente... Jure Humor 5 08-10-2004 16:09:13


La franja horaria es GMT +2. Ahora son las 00:13:35.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi