https://foro.gambas-es.org/viewtopic.php?f=5&t=842&p=4740#p4740
-----------------------------------
fabianfv
Viernes, 06 Agosto 2010, 23:46

Evaluación En Cortocircuito Y Velocidad De Gambas
-----------------------------------
Para los que no lo sepan, la implementación de Gambas de la evaluación en cortocircuito es limitada y requiere una sintaxis especial:

[code linenumbers=false syntax=gambas]
IF 11 >  9 AND IF "a" > "b" THEN.
...

IF "z" < "Z" OR IF 3 < 5 THEN
...
[/code]

Como se puede ver en el ejemplo resulta necesario volver a escribir la palabra reservada IF con cada expresión booleana que se quiera evaluar. Pero también hay restricciones adicionales:

[list]
[*] Sólo es posible utilizar evaluación en cortocircuito al utilizar la estructura condicional IF
[code linenumbers=false syntax=gambas]

DIM bExpression AS Boolean

  'Esto no se evalua en cortocircuito en Gambas
  bExpression = "z" < "Z" OR 3 < 5

  'Y esto es sintácticamente incorrecto
  bExpression = "z" < "Z" OR IF 3 < 5
[/code]
[*]  No es posible mezclar conjunción y disyunción lógica (AND y OR) en una misma expresión
[code linenumbers=false syntax=gambas]

'Esto simplemente no es posible, el compilador lo rechaza
IF ("z" < "Z" OR IF 3 < 5)  OR IF (11 >  9 AND IF "a" > "b")  THEN
[/code]
[/list]

Esta es una de las pocas falencias de Gambas con respecto a otros lenguajes. Estas limitaciones me molestan bastante por eso quise hacer esta prueba:

[list]
[*] Escribir en Gambas una clase estática que tuviera dos métodos AND y OR que permitieran realizar evaluaciones lógicas en cortocircuito.
[*] Probar el impacto que el uso de estos métodos tendría con respecto a la evaluación en cortocircuito por medio de "AND IF" y "OR IF"
[/list]

Parece obvio que el uso de las clases AND y OR escritas en Gambas debería tener un costo computacional mayor que el uso de "AND IF" y "OR IF". Bueno, pongamos esta teoría a prueba.

La clase es esta:
[code linenumbers=false syntax=gambas]
' Gambas class file
' Clase: Bool

STATIC PUBLIC FUNCTION AND(...) AS Boolean
DIM acTest, Test AS Boolean = TRUE
  FOR EACH Test IN Param
    acTest = acTest AND Test
    IF NOT acTest THEN BREAK 
  NEXT 
  RETURN acTest
END

STATIC PUBLIC FUNCTION OR(...) AS Boolean
DIM acTest, Test AS Boolean
  FOR EACH Test IN Param
    acTest = acTest OR Test
    IF acTest THEN BREAK 
  NEXT 
  RETURN acTest
END
[/code]

Para realizar pruebas escribí el siguiente código en un módulo:
[code linenumbers=false syntax=gambas]
' Gambas module file
' Módulo: Test
PUBLIC SUB Main()
DIM tcount AS Date

  tcount = Now
  PRINT "Probando Bool.OR"
  PRINT Bool.OR(11 < 7, 7 < 9, 5 < 9)
  PRINT Bool.OR(7 < 9, 11 < 7, 5 < 9)
  PRINT Bool.OR(7 < 9, 5 < 9, 11 < 7)
  PRINT Bool.OR(17 < 9, 15 < 9, 11 < 7)
  tcount = Now - tcount
  PRINT Format(tcount, "hh:mm:ss:uu")

  PRINT 

  tcount = Now
  PRINT "Probando Bool.AND"
  PRINT Bool.AND(11 < 7, 7 < 9, 5 < 9)
  PRINT Bool.AND(7 < 9, 11 < 7, 5 < 9)
  PRINT Bool.AND(7 < 9, 5 < 9, 11 < 7)
  PRINT Bool.AND(7 < 9, 5 < 9, 11 < 17)
  tcount = Now - tcount
  PRINT Format(tcount, "hh:mm:ss:uu")

  PRINT 

  tcount = Now
  PRINT "Probando Bool.AND"
  PRINT Bool.AND(1 < 2, 2 < 3, 3 < 4, 4 < 5, 5 < 6, 6 < 7, 7 < 8, 8 < 9, 9 < 10)
  tcount = Now - tcount
  PRINT Format(tcount, "hh:mm:ss:uu")

  PRINT 

  tcount = Now
  PRINT "Probando evaluación en cortocircuito de Gambas: AND IF"
  IF 1 < 2 AND IF 2 < 3 AND IF 3 < 4 AND IF 4 < 5 AND IF 5 < 6 AND IF 6 < 7 AND IF 7 < 8 AND IF 8 < 9 AND IF 9 < 10 THEN
    PRINT TRUE
  ELSE 
    PRINT FALSE
  ENDIF 
  tcount = Now - tcount
  PRINT Format(tcount, "hh:mm:ss:uu")

  PRINT 

  tcount = Now
  PRINT "Probando Bool.OR"
  PRINT Bool.OR(1 < 2, 2 < 3, 3 < 4, 4 < 5, 5 < 6, 6 < 7, 7 < 8, 8 < 9, 9 < 10)
  tcount = Now - tcount
  PRINT Format(tcount, "hh:mm:ss:uu")

  PRINT 
  tcount = Now
  PRINT "Probando evaluación en cortocircuito de Gambas: OR IF"
  IF 1 < 2 OR IF 2 < 3 OR IF 3 < 4 OR IF 4 < 5 OR IF 5 < 6 OR IF 6 < 7 OR IF 7 < 8 OR IF 8 < 9 OR IF 9 < 10 THEN
    PRINT TRUE
  ELSE 
    PRINT FALSE
  ENDIF 
  tcount = Now - tcount
  PRINT Format(tcount, "hh:mm:ss:uu")

END 
[/code]

Finalmente, estos fueron los resultados:

Probando Bool.OR
True
True
True
False
00:00:00:.003

Probando Bool.AND
False
False
False
True
00:00:00:.000

Probando Bool.AND
True
00:00:00:.000

Probando evaluación en cortocircuito de Gambas: AND IF
True
00:00:00:.000

Probando Bool.OR
True
00:00:00:.000

Probando evaluación en cortocircuito de Gambas: OR IF
True
00:00:00:.000

Como verán la única diferencia de rendimiento apreciable se da en la primera ejecución y es de sólo 3 milésimas de segundo.

Cómo no estoy seguro del resultado les pido a quienes estén interesados que repitan esta prueba en sus máquinas. Si los números les dan como a mí, entonces ya tenemos una forma de poder usar evaluación en cortocircuito en Gambas sin ninguna limitación, y si no es así, al menos podremos buscar las razones que justifiquen tanto los resultados favorables como los desfavorables.


