Como todos sabemos, Visual FoxPro brinda un entorno extremadamente rico y variado; pero a veces demasiadas cosas buenas nos llevan a adoptar malos hbitos. Al escribir cdigo existen varias vas de alcanzar el mismo resultado; pero todo frecuentemente existen diferencias significativas en rendimiento y la nica va para asegurar que nuestro cdigo est optimizado para el mejor rendimiento es comprobar, comprobar y volver a comprobar la mayor cantidad de condiciones diferentes que se puedan idear. Habiendo dicho esto, es igualmente importante reconocer que el primer requerimiento de cualquier cdigo es ser funcionalmente correcto. Al decir de Marcia Akins (Microsoft MVP, autora y co-propietaria de Tightline Computers Inc) "... hacer algo mal lo antes posible no es realmente muy til". Pero, frecuentemente tambin, tendemos a lograr la funcionalidad correcta slo al final de la historia, y una vez que algo est funcionando, simplemente nos movemos al siguiente problema. La realidad es que la mayora de los desarrolladores tpicamente revisan y optimizan su cdigo al mismo tiempo que regresan a el para agregar comentarios (es decir, nunca!). Sin embargo, al aplicar algunas reglas y tcnicas bsicas, puede asegurarse de evitar algunos de los problemas ms comunes y producir cdigo ms eficiente desde la primera vez. A medida de que lo haga con ms frecuencia, ser menor el tiempo que necesite emplear en revisar y "tunear" cdigo funcional. Esto tiene dos beneficios para todo desarrollador: Mientras menos retoques que se haga sobre el cdigo, una vez que est funcionando correctamente, ser menor la probabilidad de introducir fallos en cdigo funcional. Arreglarlo inmediatamente ahorra tiempo, no tener que revisar el cdigo, es siempre ms rpido que re-hacer para mejor rendimiento o usabilidad. El propsito de esta serie de artculos es revisar algunas de estas cosas que hacemos, cuando estamos escribiendo cdigo para asegurar que es nuestro software es tan eficiente y tan usable como sea posible y minimizar la necesidad de revisar cdigo que trabaja bien para optimizarlo. Comenzaremos con algo bsico y luego, ms adelante en esta serie, tendremos algo ms avanzado.
y ahora nos pregunta si queremos quitar la clase de memoria? Cmo se supone que la arreglemos si NO lo hacemos? Para hacer las cosas aun peores, la opcin seleccionada de forma predeterminada es "Ignore"! Entonces, si ha tratado de insertar una lnea nueva presionando la tecla Intro como el primer paso de su modificacin (y Cun frecuentemente no es lo primero que hacemos?) - este dilogo idiota relampaguea en su pantalla, y se va, seleccionando "ignorar" y no pasa nada. Ahora vea, despus de todo, yo soy un desarrollador y seguramente si intento modificar una definicin de clase realmente DESEO hacerlo? Que hace a VFP pensar que asume que yo no se lo que estoy haciendo? Esto es realmente muy molesto, por no decir insultante!
Ahora considere Con cunta frecuencia tiene ese tipo de dilogos en sus aplicaciones? La pregunta clsica es "Est seguro?". He aqu un ejemplo, el usuario abre la ventana de bsqueda, encuentra algn valor y trata de encontrar un registro. Entonces tiene que seleccionar, desde las opciones del desarrollador, "Eliminar". Un dilogo diciendo: "Esto va a eliminar el registro, est seguro?" con "NO" como opcin predeterminada (Es su turno de proteccin" infalible", amigos ...) Cun insultante es esto? Por supuesto, ellos desean eliminar el registro, gastan justamente 20 minutos buscando el registro, y ahora le pregunta si est seguro de que eso era lo que quera hacer? Por supuesto, oigo que est diciendo, siempre existe la posibilidad de que oprima Eliminar accidentalmente. Pero quin es el culpable? La respuesta, DEL DESARROLLADOR! El desarrollador es el nico que hace posible que oprima "eliminar" por accidente, nadie ms. Si la funcionalidad eliminar es tan sensitiva, entonces la interfaz de usuario est mal hecha que permite la casualidad. (usted pregunta "Est seguro?" cuando el usuario desea Agregar un registro, o Guardar cambios ...?). Por qu no habilita el botn "eliminar" una posible accin de tal forma que el usuario tiene que hacer algo para iniciar el proceso y no entonces tener que lidiar con "Esto va a eliminar un registro" seguido por "Est seguro?", seguido por "Est realmente, realmente seguro" y as hasta el infinito. Al final de este da, el desarrollador, tiene que o ejecutar el comando eliminar o cancelar la operacin - mejor que advertir, y darle la opcin de cancelar, antes ellos han gastado su tiempo en el proceso.
*!* Inicializa el contador de registros lnCnt = 0 lcOfRex = " de " + TRANSFORM( RECCOUNT( ALIAS() ) ) SCAN *!* Actualiza el valor mostrado del progreso lnCnt = lnCnt + 1 lcTxt = 'Procesando Registro ' + TRANSFORM( lnCnt ) + lcOfRex WAIT lcTxt WINDOW NOWAIT
Ahora, lo interesante acerca este proceso era que se ejecutaba contra una tabla que ahora contiene ms de 125.000 registros. Y qu? Escucho que dice, bueno el tiempo que toma para ejecutar el proceso fue cerca de 3 minutos. Pero intente este cdigo en su PC local:
LOCAL lnCnt, lcOfRex, lnSt, lnNum, lcTxt, lnEn lnCnt = 0 lcOfRex = " de 125000" lnSt = SECONDS() FOR lnNum = 1 TO 125000 lnCnt = lnCnt + 1 lcTxt = 'Procesando Registro ' + TRANSFORM( lnCnt ) + lcOfRex WAIT lcTxt WINDOW NOWAIT NEXT lnEn = SECONDS() ? STR( lnEn - lnSt, 8, 4 )
Ahora, en su PC este cdigo tardar unos 32 segundos para ejecutarse y qu hace? NADA de nada! La pantalla que muestra ni siquiera es legible. La nica conclusin a la que podemos llegar es que este cdigo intil ha tomado el 15% del total del tiempo de ejecucin. Intente la siguiente versin del mismo cdigo:
LOCAL lnCnt, lcOfRex, lnSt, lnNum, lcTxt, lnEn lnCnt = 0 lcOfRex = " de 125000" lnSt = SECONDS() FOR lnNum = 1 TO 125000 lnCnt = lnCnt + 1 IF MOD( lnCnt, 10000 ) = 0 lcTxt = 'Procesando Registro ' + TRANSFORM( lnCnt ) + lcOfRex
WAIT lcTxt WINDOW NOWAIT ENDIF NEXT lnEn = SECONDS() ? STR( lnEn - lnSt, 8, 4 )
Esto, en mi mquina demora menos de 0.3 de un segundo - Es 100 veces ms rpido! Ahora, si consideramos el proceso en cuestin, con 125 000 registros empleaba aproximadamente 3 minutos, lo que significa que recorre aproximadamente 700 registros por segundo. Puede el usuario siquiera ver la actualizacin del mensaje a esa velocidad? tiene alguna utilidad? Por supuesto no, entonces, por qu utilizarlo? La cuestin es Cul es el intervalo razonable para actualizar la ventana? Desafortunadamente no hay una respuesta "correcta"; pero puedo sugerir aqu, que aplique un poco de sentido comn. El primer requerimiento es que necesita tener alguna idea acerca de la longitud total del proceso en cuestin. Obviamente si el proceso se ejecuta durante tres horas, actualizar cada diez segundos es innecesario probablemente, a la inversa si tarda tres minutos, entonces un intervalo de actualizacin cada 10 segundos parece razonable. La regla general, que yo suelo utilizar es intentar actualizar la informacin de usuario 200 veces por proceso (es decir cada 0.5% de cumplimiento). Mi barra de progreso, tiene entonces 200 unidades y yo configuro mi intervalo de actualizacin calculando el progreso esperado que constituya el 0,5% del total al tomar el nmero de registros, y el promedio de tiempo para cada proceso. Cmo se el tiempo promedio de las pruebas? Cuando estoy desarrollando el cdigo, lo pruebo. Baso mi evaluacin del tiempo de procesamiento promedio en una verificacin que emplea un volumen de datos que es al menos 50% ms largo del que yo espero obtener en produccin. Si, esto significa a veces que mi actualizaciones son muy rpidas, al principio, cuando el sistema primero entra en uso; pero cuando crece el volumen de datos, la muestra se acerca a mi 0,5% de realizacin. Incluso si estuve mal en mi estimacin, y el proceso termina siendo dos veces ms largo, por registro, como yo esperaba estoy actualizando aun la visualizacin cada 1% de camino - lo que en el proceso que tomaba tres horas significa una actualizacin en la ventana cada 100 segundos. Todo esto puede sonar muy sencillo y obvio; pero como es tan frecuente en el desarrollo de aplicaciones, algo pequeo hace la diferencia - especialmente cuando son obvios para el usuario final.