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:
- Sólo es posible utilizar evaluación en cortocircuito al utilizar la estructura condicional IF
- No es posible mezclar conjunción y disyunción lógica (AND y OR) en una misma expresión
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:
- 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"
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:
' 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
' 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
Para realizar pruebas escribí el siguiente código en un módulo:
' 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
' 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")
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")
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")
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")
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")
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
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.