![]() |
|
||||||||
|
|
Alojado en: Recomienda esta pagina a un amigo ![]() Servicios Gratuitos
Articulos relacionados
Enlaces recomendados |
Sugerencias sobre ASP para la mejora del rendimiento y el estilo (I)Len Cardinal, Consultor senior, Microsoft Consulting Services Adaptación de un artículo
(en inglés) de Nancy Cluts Resumen: este artículo presenta una serie de sugerencias para
la optimización Contenido Introducción IntroducciónEl rendimiento es una característica fundamental y, de hecho, si una aplicación no se diseña desde un principio teniéndolo en cuenta, más adelante será preciso volver a desarrollarla. Dicho de esta manera uno se pregunta: ¿existe alguna estrategia eficaz para maximizar el rendimiento de la aplicación ASP (Páginas Active Server)? Este artículo proporciona una serie de sugerencias que permiten optimizar las aplicaciones ASP y Visual Basic® Scripting Edition (VBScript) y en él se discuten las muchas trampas y dificultades a las que se ha tenido que hacer frente. Las sugerencias que se enumeran se han utilizado en distintos sitios, incluyendo el de Microsoft, http://www.microsoft.com, y se ha comprobado que funcionan a la perfección. Este artículo da por sentado que el lector conoce los aspectos básicos del desarrollo de ASP, incluidos VBScript y/o JScript, las aplicaciones y sesiones ASP y el resto de objetos intrínsecos ASP (Request, Response y Server). A menudo el rendimiento de ASP depende de mucho más que el propio código ASP. En lugar de cubrir todo el tema en un solo artículo, se han enumerado al final del mismo los recursos relacionados con el rendimiento. Estos vínculos tratan sobre temas relacionados o no con ASP, por ejemplo, Objetos de datos ActiveX® (ADO), Modelo de objetos componentes (COM), bases de datos y la configuración de Internet Information Server (IIS). Se trata de algunos de nuestros vínculos preferidos y recomendamos que los visite. Sugerencia 1: Almacenar en caché datos utilizados frecuentemente en el servidor WebUna página ASP típica recupera los datos desde el almacenamiento central de datos y, a continuación, convierte los resultados en lenguaje de marcado de hipertexto (HTML). Independientemente de la velocidad de la base de datos, recuperar los datos desde la memoria resulta un proceso mucho más rápido que recuperarlos desde dicho almacenamiento central de datos. La lectura de los datos en un disco local también se lleva a cabo más rápidamente que si se recuperan desde la base de datos. Por otra parte, también se puede incrementar el rendimiento almacenando los datos en caché en el servidor Web, ya sea en la memoria o en el disco. El almacenamiento en caché constituye un mecanismo clásico que permite el equilibrio entre el espacio y el tiempo. Si se almacenan los elementos adecuados, se puede observar un impresionante aumento en el rendimiento. Para que la caché resulte efectiva ésta debe almacenar los datos que se vuelven a utilizar con relativa frecuencia y aquellos que pueden resultar (moderadamente) costosos de actualizar. Contar con datos obsoletos en la caché supone malgastar la memoria. Los datos que no cambian con excesiva frecuencia son los candidatos idóneos para que se almacenen en caché, ya que uno no debe preocuparse por la sincronización con la base de datos después de un tiempo; listas de cuadros combinados, tablas de referencia, recortes DHTML, cadenas de lenguaje de marcado extensible (XML), elementos de menú y variables de configuración de los sitios (incluyendo nombres de origen de datos (DSN), direcciones de protocolo de Internet (IP) y rutas Web). Sin embargo, es necesario señalar que lo que se almacena en caché es la presentación de los datos y no los datos en sí. Si una página ASP no se modifica con demasiada frecuencia y resulta costoso almacenarla en caché (por ejemplo, un catálogo completo de productos), se debe considerar la posibilidad de generar previamente el HTML, en lugar de volver a escribirlo para cada solicitud. ¿Dónde deben almacenarse los datos y cuáles son las principales estrategias para el almacenamiento en caché? Por regla general los datos se almacenan, bien en la memoria, bien en los discos del servidor Web. Las dos sugerencias que se proporcionan a continuación cubren ambas opciones. Sugerencia 2: Almacenar en caché datos utilizados frecuentemente en el objeto de aplicación o de sesiónLos objetos Application y Session ASP resultan unos contenedores adecuados para el almacenamiento de los datos, que se pueden asignar tanto al objeto Application como a Session y que permanecen en la memoria entre solicitudes HTTP. Los datos de la sesión se almacenan por usuario, mientras que los de la aplicación los comparten todos los usuarios. ¿En qué punto suele cargar los datos en la aplicación o la sesión?
Con frecuencia los datos se cargan durante el inicio de la sesión o de
la aplicación, para lo que es necesario agregar el código adecuado a <% Function GetEmploymentStatusList Dim d d = Application("EmploymentStatusList") If d = "" Then ' La función FetchEmploymentStatusList (no se muestra) ' busca los datos en la BD y devuelve una matriz d = FetchEmploymentStatusList() Application("EmploymentStatusList") = d End If GetEmploymentStatusList = d End Function %> Se podrían emplear funciones similares con cada grupo de datos necesario. ¿En qué formato deben almacenarse los datos? Se puede almacenar
cualquier tipo Variant, ya que se trata de variables de secuencia. Por
ejemplo, se pueden almacenar cadenas, enteros o matrices. A menudo se
almacenará el contenido de un recordset ADO en uno de estos tipos de
variables. Para extraer los datos del recordset ADO, se pueden copiar
manualmente en las variables VBScript, un campo por vez. Resulta más rápido
y sencillo utilizar una de las persistentes funciones del recordset ADO GetRows(),GetString()
(en inglés) o Save()
(ADO 2.5) (en inglés). No es el objetivo de este artículo proporcionar
todos los detalles sobre este tema, sin embargo, sí que se ofrece un
ejemplo ilustrativo sobre cómo utilizar ' Obtener Recordset, devolver como matriz Function FetchEmploymentStatusList Dim rs Set rs = CreateObject("ADODB.Recordset") rs.Open "seleccionar StatusName, StatusID en EmployeeStatus", _ "dsn=employees;uid=sa;pwd=;" FetchEmploymentStatusList = rs.GetRows() " Devolver datos como matriz rs.Close Set rs = Nothing End Function Un refinamiento aún mayor sería almacenar en caché el HTML de la lista en lugar de la matriz. Aquí se muestra un sencillo ejemplo de cómo hacerlo: ' Obtener Recordset, devolver como lista de opción HTML Function FetchEmploymentStatusList Dim rs, fldName, s Set rs = CreateObject("ADODB.Recordset") rs.Open "seleccionar StatusName, StatusID en EmployeeStatus", _ "dsn=employees;uid=sa;pwd=;" s = "<seleccionar nombre=""EmploymentStatus">" & vbCrLf Set fldName = rs.Fields("StatusName") ' Enlace de campos ADO Do Until rs.EOF ' La siguiente línea viola Evitar la concatenación de las cadenas..., ' pero no importa ya que estamos creando una caché s = s & " <option>" & fldName & "</option>" & vbCrLf rs.MoveNext Loop s = s & "</select>" & vbCrLf rs.Close Set rs = Nothing ' Consultar Adquirir los recursos en el último... FetchEmploymentStatusList = s ' Devolver datos como cadena End Function En las condiciones adecuadas se pueden almacenar en caché los propios recordsets ADO en el ámbito de aplicación o de sesión, con la salvedad de dos casos:
Si no se puede garantizar que se van a cumplir dichos requisitos, los recordsets ADO no se deben almacenar en caché. En la sugerencias Evitar almacenar en caché componentes no ágiles... y No almacenar en caché conexiones... que aparecen a continuación se discuten los principales riesgos que supone el almacenamiento de objetos COM en el ámbito de aplicación o de sesión. En esta circunstancia, los datos permanecen allí hasta que el desarrollador decide modificarlos con la programación, hasta que termina la sesión o hasta que se reinicia la aplicación Web. ¿Qué ocurre si es necesario actualizar los datos? Para forzar manualmente una actualización de los datos de la aplicación, se puede llamar a una página ASP a la que sólo tenga acceso el administrador para que actualice los datos. Otra alternativa es actualizarlos automáticamente de forma periódica utilizando una función. El ejemplo siguiente almacena una marca de tiempo con los datos y los actualiza después de un intervalo de tiempo concreto. <% ' error no mostrado... Const UPDATE_INTERVAL = 300 ' Actualizar intervalo, en segundos ' Función para devolver lista de estado Function GetEmploymentStatusList UpdateEmploymentStatus GetEmploymentStatusList = Application("EmploymentStatusList") End Function ' Actualizar periódicamente los datos en caché Sub UpdateEmploymentStatusList Dim d, strLastUpdate strLastUpdate = Application("LastUpdate") If (strLastUpdate = "") Or _ (UPDATE_INTERVAL < DateDiff("s", strLastUpdate, Now)) Then ' Nota: se pueden obtener dos o más llamadas. Es suficiente y simplemente ' resultará en varias búsquedas innecesarias (existe una solución) ' La función FetchEmploymentStatusList (no se muestra) ' busca los datos en la BD y devuelve una matriz d = FetchEmploymentStatusList() ' Actualizar el objeto de aplicación. Utilizar Application.Lock() ' para garantizar la coherencia de los datos Application.Lock Application("EmploymentStatusList") = d Application("LastUpdate") = CStr(Now) Application.Unlock End If End Sub Para ver otro ejemplo consulte World’s Fastest ListBox with Application Data (en inglés). Es necesario advertir que almacenar en caché matrices de gran tamaño en los objetos Session o Application no es muy recomendable. Antes de poder tener acceso a cualquiera de los elementos de la matriz, la semántica de los lenguajes de secuencias requiere que se realice una copia temporal de la matriz completa. Por ejemplo, si se almacena en caché una matriz de cadenas de 100.000 elementos que asigne códigos postales norteamericanos a estaciones meteorológicas locales en el objeto Application, ASP debe copiar primero las 100.000 estaciones meteorológicas antes de que se pueda extraer una sola cadena. En este caso, resultaría mucho mejor elaborar un componente personalizado con un método también personalizado que permitiera almacenar las estaciones, o bien, utilizar uno de los componentes de diccionario. Un comentario adicional en la misma línea de no tirar las frutas frescas con las pochas: las matrices proporcionan un mecanismo rápido para la consulta y el almacenamiento de datos clave que son contiguos en la memoria. La indización de un diccionario constituye un proceso más lento que la de una matriz. Se debe seleccionar la estructura de datos que ofrezca el mejor rendimiento en cada caso. Sugerencia 3: Almacenar en caché datos y HTML en los discos del servidor WebPuede que en ocasiones el volumen de datos que se deben almacenar en la memoria caché sea demasiado elevado. No obstante, el término “demasiado” constituye una apreciación, ya que depende de la cantidad de memoria que se desea utilizar, así como del número de elementos que se quieren almacenar en caché y la frecuencia en la que dichos elementos se recuperan. En cualquier caso, si son demasiados los datos que se deben guardar, tenga en cuenta que siempre podrá almacenarlos en archivos XML o de texto en los discos duros de los servidores Web. Puede combinar el almacenamiento en discos y en memoria para crear una óptima estrategia de almacenamiento en caché para su sitio. Hay que tener en cuenta que cuando se está analizando el rendimiento de una única página ASP, la recuperación de los datos del disco puede que no resulte una operación más rápida que su recuperación desde la base de datos. Sin embargo, el almacenamiento en caché reduce la carga que deben soportar la base de datos y la red. En condiciones de cargas mayores se mejorará considerablemente el rendimiento general. El almacenamiento en caché puede ser muy útil cuando se desean almacenar los resultados de una consulta costosa, como es el caso de las tablas múltiples, de procedimientos almacenados más complejos o de grandes conjuntos de resultados. Pero, como siempre, se deben comparar otros esquemas. ASP y COM proporcionan algunas herramientas que permiten construir esquemas de almacenamiento basados en discos. Las funciones Save() y Open() del recordset ADO guardan y cargan los recordsets desde el disco. Se pueden utilizar ambos métodos para volver a escribir el código de muestra de la anterior sugerencia, Almacenar en caché datos utilizados frecuentemente en el objeto de aplicación..., sustituyendo Save() por el código que desarrolla el objeto Application. Existen otros componentes que funcionan con archivos:
Por último, otra alternativa posible es el almacenamiento en caché de la presentación de los datos en un disco en lugar de los propios datos. El HTML procesado previamente puede almacenarse en disco como un archivo de extensión .htm o .asp, archivos a los que los hipervínculos pueden conducir directamente. Se puede automatizar el proceso de generación de HTML utilizando algunas de las herramientas del mercado como XBuilder (en inglés) o las características para la publicación en Internet de Microsoft® SQL Server™. Otra opción es #incluir miniprogramas de HTML en un archivo .asp. También se pueden leer los archivos HTML desde el disco utilizando FileSystemObject, o bien, emplear XML para el procesamiento previo (en inglés). Sugerencia 4: Evitar almacenar en caché componentes no ágiles en los objetos de aplicación o de sesiónMientras que el almacenamiento en caché de los datos en el objeto Application o Session puede ser una excelente idea, el mismo tipo de almacenamiento de objetos COM puede suponer ciertas dificultades. Puede resultar tentador guardar objetos COM utilizados frecuentemente en los objetos Application o Session. Desafortunadamente, muchos de estos objetos COM, incluyendo aquellos desarrollados en Visual Basic 6.0 o posterior, pueden ocasionar serios cuellos de botella cuando se almacenan en los objetos Application o Session. Más específicamente, cualquier componente que no sea ágil
(en inglés) puede producir cuellos de botella en los objetos Session
o Application. Un componente ágil es un componente marcado como
Los componentes configurados (Microsoft Transaction Server (MTS)/biblioteca COM+ y aplicaciones/paquetes del servidor) no son ágiles a menos que se consideren Neutral. Los componentes de subprocesamiento controlado, entre otros componentes no ágiles, ofrecen mejores resultados en el ámbito de página (es decir, se crean y se destruyen en una sola página ASP). En IIS 4.0, un componente marcado como IIS 5.0 enviará un mensaje de error si se intenta almacenar un
componente no ágil creado con ¿Qué es lo que ocurre si se almacenan en caché componentes no ágiles? Un componente de este tipo almacenado en el objeto Session “bloqueará” la sesión a un subproceso de trabajo ASP. ASP mantiene un conjunto de procesos de trabajo que se ocupan de las solicitudes. Normalmente el primer subproceso de trabajo que estuviera libre se ocuparía de la nueva solicitud. Si se bloquea una sesión a un subproceso, la solicitud debe esperar hasta que el subproceso asociado se encuentre disponible. A continuación presentamos una analogía que bien puede servir para explicarlo: uno va al supermercado, selecciona varios tipos de artículos comestibles y abona el importe en la caja nº 3. Imagine que a partir de ese momento, siempre que compre artículos en ese supermercado, debe abonarlos en la misma caja nº 3, aunque haya menos personas esperando en otras cajas o algunas de ellas se encuentre vacía. El almacenamiento de componentes no ágiles en el ámbito de aplicación tiene un efecto aún peor sobre el rendimiento. ASP debe crear un subproceso espacial para ejecutarlos, lo que tiene dos consecuencias: todas las llamadas deben realizarse en serie y se deben ordenar en dicho subproceso. El ordenamiento supone que los parámetros deben almacenarse en un área compartida de memoria; se realiza un costoso cambio de contexto en el subproceso especial; se ejecuta el método del componente; se ordenan los resultados en el área compartida; y un cambio adicional de contexto devuelve el control al subproceso original. La serialización implica que los métodos se ejecutan de uno en uno. No se puede dar la circunstancia de que dos subprocesos de trabajo ASP ejecuten simultáneamente métodos en el componente compartido, ya que esto acabaría con la concurrencia, especialmente en equipos con varios procesadores. Y aún peor, todos los componentes no ágiles en el ámbito de aplicación comparten un subproceso (“Host STA”), de forma que los efectos de la serialización son aún más marcados. ¿Resulta demasiado confuso? Aquí tiene algunas reglas generales. Si está desarrollando objetos en Visual Basic (6.0) o posterior, no debe almacenarlos en caché en los objetos Application o Session. Si desconoce el modelo de subprocesamiento de un objeto, es mejor que no lo almacene. En lugar de almacenar objetos no ágiles debe crearlos y liberarlos en cada página. Los objetos se ejecutarán directamente en el subproceso de trabajo, con lo que no se producirán ni la serialización ni la ordenación. El rendimiento será el adecuado si los objetos COM se ejecutan en un cuadro de IIS y si no tardan demasiado en iniciarse y destruirse. Tenga en cuenta que los objetos de subprocesamiento único no deben utilizarse de este modo. Preste atención: ¡VB puede crear objetos de subprocesamiento único! Si debe utilizar objetos de subprocesamiento único de esta manera (como una hoja de cálculo de Microsoft Excel), no espere un buen rendimiento. Los recordsets ADO pueden almacenarse en caché de forma segura cuando ADO se marca como de subprocesamiento libre. Para marcar ADO como de subprocesamiento libre, utilice el archivo Makfre15.bat, que se ubica normalmente en el directorio \\Archivos de programa\Archivos comunes\System\ADO. Advertencia: ADO no debe marcarse como de subprocesamiento libre si no se utiliza Microsoft Access como base de datos. El recordset ADO siempre debe estar desconectado. Por regla general, si no se puede controlar la configuración de ADO del sitio (por ejemplo, el caso de los fabricantes independientes de software [ISV], que distribuyen aplicaciones Web a los clientes y éstos de ocupan de sus propias configuraciones), probablemente sea mejor que no almacene en caché los recordsets. Los componentes de diccionario también se incluyen en la categoría de objetos ágiles. El objeto LookupTable carga sus datos desde el archivo de datos y resulta muy útil para los datos de cuadros combinados y como información de configuración. PageCache de Duwamish Books (en inglés) proporciona la semántica del diccionario, al igual que el diccionario Caprock. Estos objetos, o derivados, pueden formar la base de una eficaz estrategia de almacenamiento. Tenga en cuenta que el objeto Scripting.Dictionary NO es ágil y que no debe almacenarse en el ámbito de aplicación o de sesión. Sugerencia 5: No almacenar en caché conexiones de la base de datos en los objetos de aplicación o de sesiónAlmacenar en caché conexiones ADO no es por lo general una buena estrategia. Si un objeto Connection se almacena en el objeto Application y se utiliza en todas las páginas, éstas competirán por utilizar la conexión. Si el objeto Connection se almacena en el objeto Session ASP, se creará una conexión a la base de datos para cada usuario. Con esto se pierden los beneficios que suponía la agrupación de conexiones y se incrementa en exceso la carga tanto en el servidor Web como en la base de datos. En lugar de almacenar las conexiones a la base de datos, una alternativa mejor es crear y destruir los objetos ADO en cada una de las páginas ASP que los utilizan. Se trata de un mecanismo muy eficaz ya que IIS incorpora la agrupación de conexiones. De forma más precisa, IIS habilita automáticamente la agrupación de conexiones de OLEDB y ODBC. Así se garantiza que la creación y posterior destrucción de las conexiones de cada página ofrece resultados positivos. Dado que los recordsets almacenan una referencia a la conexión a la base de datos, no se deben almacenar en caché en el objeto Application o Session. No obstante, sí que se pueden almacenar en caché de forma segura los recordsets desconectados, ya que estos últimos no guardan referencia alguna a la conexión de datos. Para desconectar un recordset, siga los dos pasos siguientes: Set rs = Server.CreateObject("ADODB.RecordSet") rs.CursorLocation = adUseClient ' paso 1 ' Poblar el recordset con datos rs.Open strQuery, strProv ' desconectar el recordset del proveedor de datos y el origen de datos rs.ActiveConnection = Nothing ' paso 2 Puede obtener más información sobre la agrupación de conexiones en las referencias a ADO y SQL Server. Sugerencia 6: Utilizar prudentemente el objeto de sesiónDespués de haber roto una lanza en favor de las virtudes del almacenamiento en caché en las aplicaciones y en las sesiones, vamos a sugerir evitar el objeto Session. Las sesiones pueden suponer ciertas dificultades cuando se utilizan en sitios con mucha actividad, como veremos más adelante. Por sitios con mucha actividad generalmente entendemos aquellos que solicitan cientos de páginas por segundo o los que visitan simultáneamente miles de usuarios. Esta sugerencia nos parece aún más importante en el caso de los sitios que se deben escalar horizontalmente, es decir, aquellos que utilizan varios servidores para acomodar la carga o para implementar la tolerancia a los errores. En sitios más pequeños, como los de una intranet, las ventajas que proporcionan las sesiones bien compensan los inconvenientes. Recapitulemos: ASP crea automáticamente una sesión para cada usuario que realiza la solicitud al servidor Web. Cada sesión dispone de casi 10 KB de memoria extra (siempre por encima de la cantidad de datos almacenados en la sesión) y ralentiza un poco todo el proceso. La sesión permanece viva durante un período de tiempo de espera configurable, que generalmente es de 20 minutos. El principal problema que plantean las sesiones no es el rendimiento, sino la escalabilidad. Las sesiones no se extienden a los servidores Web; una vez se ha creado una sesión en un servidor, sus datos permanecen allí. Esto significa que si se utilizan las sesiones en una granja Web, se debe diseñar una estrategia para las solicitudes de cada usuario de forma que siempre se dirijan al servidor en el que existe la sesión del usuario. Esto se denomina “pegar” un usuario al servidor Web. El término “sesiones pegadas” deriva de él. Si se produjera algún error en el servidor Web, se perdería el estado de la sesión de los usuarios que se han “pegado”, ya que las sesiones no se almacenan en el disco. Las estrategias de implementación de este tipo de sesiones incluyen soluciones de hardware y software como el equilibrio de carga para redes (en inglés) en Windows 2000 Advanced Server y Local Director de Cisco, que pueden implementarlas, a expensas de cierta escalabilidad. Estas soluciones no son perfectas. Confirmar una solución de software propia en este punto no es muy recomendable (solíamos utilizar filtros ISAPI, la eliminación de URL, etc.). El objeto Application tampoco se extiende a los servidores; si es necesario compartir y actualizar los datos de la aplicación por la granja Web, será preciso utilizar la base de datos central. No obstante, se debe señalar que los datos de una aplicación de sólo lectura aún son de utilidad en las granjas Web. Casi con toda seguridad, en sitios de misión crítica se deseará distribuir al menos dos servidores Web, aunque simplemente sea por incrementar el tiempo de actividad (mantenimiento del servidor y control de errores). Por otra parte, para diseñar una aplicación de misión crítica se deben implementar las “sesiones pegadas” o simplemente evitar las sesiones de cualquier tipo, así como cualquier otra técnica de control del estado que almacene a los usuarios en servidores Web por separado. Si no desea utilizar sesiones, asegúrese de desactivarlas. Esta operación se puede realizar, en el caso de la aplicación, con el Administrador de servicios de Internet (consultar la documentación de ISM). Si, por el contrario, decide utilizar sesiones, siempre puede minimizar su impacto en el rendimiento de varias formas distintas. Puede mover el contenido que no requiera sesiones (por ejemplo, pantallas de ayuda, áreas de visitantes, etc.) a otra aplicación ASP en la que se hayan desactivado las sesiones. Utilizando el esquema de página a página, se sugiere a ASP que el objeto de sesión no es necesario en una página concreta; utilice la directiva siguiente situada en la parte superior de la página ASP: <% @EnableSessionState=False %> Una buena razón por la que conviene utilizar esta directiva es que
las sesiones crean un interesante problema con los conjuntos de marcos.
ASP garantiza que sólo se ejecutará una solicitud de la sesión por
vez. De esta manera, si el explorador solicita varias páginas para un sólo
usuario, la sesión sólo se ocupará de una solicitud ASP; con ello se
evitan los problemas ocasionados por el subprocesamiento múltiple
cuando se tiene acceso al objeto Session. Desafortunadamente, se
obtiene como resultado que todas las páginas de un conjunto de marcos
aparecen en serie, una tras otra, en lugar de hacerlo simultáneamente.
Puede que el usuario se vea obligado a esperar algún tiempo hasta que
aparezcan todos los marcos. La moraleja de esta pequeña historia es la
siguiente: si ciertas páginas de conjuntos de marcos no dependen de la
sesión, es necesario informar de ello a ASP utilizando la directiva Como alternativa a la utilización del objeto Session existen varias opciones que permiten controlar el estado de la sesión. Con tamaños reducidos (menos de 4 KB), generalmente recomendamos que se utilicen las cookies, las variables QueryString y las de formulario oculto. Cuando se trata de tamaños de datos mayores como los de un carro de la compra, la elección más adecuada es una base de datos central. El tema de las técnicas de control de estado en las granjas Web ha generado mucha literatura; se pueden consultar algunas referencias en la sección relativa al estado de la sesión. Sugerencia 7: Encapsular el código en los objetos COMSi se dispone de mucho VBScript o JScript, siempre se puede mejorar el rendimiento moviendo el código a un objeto COM compilado. El código compilado generalmente se ejecuta con mayor rapidez que el interpretado. Los objetos COM compilados pueden tener acceso a otros objetos COM gracias a un “enlace en tiempo de compilación”, un método más eficaz para invocar métodos de objetos COM que el de “enlace en tiempo de ejecución” que emplea la secuencia. Existen más ventajas (además de la mejora del rendimiento) al encapsular el código en objetos COM:
Los objetos COM también tienen sus inconvenientes, incluyendo el tiempo de desarrollo inicial y la necesidad de nuevas habilidades de programación. Encapsular pequeñas cantidades de ASP puede ir en detrimento del rendimiento en lugar de mejorarlo. Esto ocurre normalmente cuando una pequeña cantidad de código ASP se incluye en el objeto COM. En este caso, la carga que supone crear e invocar el objeto COM supera a las ventajas de utilizar código compilado. Se trata de una cuestión de ensayo y error el determinar qué combinación de secuencia ASP y código de objetos COM genera el mejor resultado en cuanto a rendimiento. Microsoft ha mejorado enormemente el rendimiento de las secuencias y de ADO en Windows 2000/IIS 5.0 en comparación con Windows NT® 4.0/IIS 4.0. De esta forma, la ventaja del rendimiento que se disfrutaba al utilizar el código compilado sobre el código ASP se ha reducido con la introducción de IIS 5.0. Para conocer algunos interesantes debates sobre las ventajas e inconvenientes de utilizar objetos COM en ASP, consulte Guía del componente ASP y Programming Distributed Applications with COM and Microsoft Visual Basic 6.0 (en inglés). Si desea distribuir los componentes COM, es importante que realice una prueba de carga (en inglés) de los mismos. De hecho, se deberían realizar por norma pruebas de este tipo en todas las aplicaciones ASP. Sugerencia 8: Adquirir los recursos en el último momento y liberarlos cuanto antesSe trata de una pequeña sugerencia. En general, es mejor adquirir los recursos tarde y liberarlos pronto. Esto se refiere tanto a objetos COM como a los controladores de archivos y demás recursos. Las conexiones y recordsets ADO son los candidatos idóneos para esta
optimización. Cuando haya terminado de utilizar un recordset, por
ejemplo, tras crear una tabla con sus datos, se debe liberar
inmediatamente, en lugar de esperar hasta el final de la página.
Establecer la variable de VBScript como Sugerencia 9: La ejecución fuera de proceso permite el equilibrio entre el rendimiento y la confiabilidadTanto ASP como MTS/COM+ presentan una serie de opciones de configuración que permiten compensar la confiabilidad y el rendimiento. Es preciso entender dichas compensaciones cuando se está construyendo y distribuyendo una aplicación. Opciones de ASPLas aplicaciones ASP pueden configurarse de forma que se ejecuten de tres formas distintas. Con IIS 5.0, el “nivel de aislamiento” de la terminología se ha introducido para describir dichas opciones. Los tres valores del nivel de aislamiento son bajo, medio y alto:
Entonces, ¿cuál es la opción más adecuada? En IIS 4.0 se podía observar un declive en el rendimiento cuando la aplicación se ejecutaba fuera de proceso. Se ha trabajado a conciencia en este tema en IIS 5.0 y se ha logrado minimizar el coste de la ejecución de las aplicaciones ASP fuera de proceso. De hecho, en la mayoría de las comprobaciones, las aplicaciones ASP fuera de proceso en IIS 5.0 se ejecutan más rápidamente que las aplicaciones en proceso en IIS 4.0. No obstante, las aplicaciones en proceso generan (con un nivel de aislamiento bajo) el mejor rendimiento en ambas plataformas. A pesar de esta circunstancia, resulta difícil obtener beneficios del nivel bajo si la frecuencia de aciertos o la salida máxima son relativamente bajas. Por tanto, es mejor no alcanzar el nivel de aislamiento bajo hasta que se necesiten cientos o miles de páginas por segundo y por servidor Web. Como siempre, se deben comprobar las distintas configuraciones para determinar las compensaciones se que desean obtener. Nota: cuando se ejecutan aplicaciones ASP fuera de proceso (con aislamiento medio o alto), se ejecutan en MTS en NT4 y en COM+ en Windows 2000. Es decir, en NT4 se ejecutan desde Mtx.exe y, en Windows 2000, por su parte, lo hacen en DllHost.exe. Se pueden ver los procesos en el Administrador de tareas. También se pueden conocer los detalles de la configuración de los paquetes MTS o de las aplicaciones COM+ por parte de IIS para aplicaciones ASP fuera de proceso. Opciones de COMLos componentes COM también presentan tres opciones de configuración que, sin embargo, no son completamente análogas a las de ASP. Los componentes COM pueden estar: “no configurados”, configurados como aplicaciones de biblioteca o configurados como aplicaciones de servidor. No configurado significa que el componente no se ha registrado con COM+ y que se ejecutará en el espacio de proceso de quien realizó la llamada, es decir, se encuentran “en proceso”. Las aplicaciones de biblioteca también se encuentran en proceso, sin embargo se benefician de los servicios de COM+, incluyendo la seguridad, las transacciones y el soporte del contexto. Las aplicaciones de servidor se configuran para ejecutarse en su propio espacio de proceso. Puede que vea unos beneficios importantes en el uso de componentes no configurados comparados con las aplicaciones de biblioteca, lo que sí está claro es que verá unos beneficios mucho mayores en cuanto al rendimiento si utiliza estas últimas en lugar de las aplicaciones de servidor. Esto se debe a que las aplicaciones de biblioteca se ejecutan en el mismo proceso que ASP, mientras que las del servidor lo hacen en su propio espacio de proceso. Las llamadas de inter-proceso resultan mucho más costosas que las llamadas en proceso. Asimismo, cuando se pasan datos, por ejemplo, recordsets, entre procesos, todos ellos se deben copiar entre los dos procesos. ¡He aquí un problema! Cuando se utilizan aplicaciones de servidor
COM, si se pasan objetos entre ASP y COM, es preciso asegurarse de que
dichos objetos implementan el denominado “subprocesamiento por
valor” o MBV, ya que los que lo hacen se copian a sí mismos de un
proceso a otro. Esto resulta mucho mejor que la otra alternativa, que
consistiría en que el objeto debe permanecer en el proceso del creador
y que el resto de los procesos llamarían repetidamente al proceso que
se está creando para que utilice el objeto. Los recordsets ADO
desconectados se subprocesarán por valor; los conectados no. Scripting.Dictionary
no implementa MBV y no debería pasarse entre procesos. Por último,
enviamos un mensaje a los programadores de VB: MBV NO se obtiene pasando
el parámetro ¿Qué se puede hacer?Si tuviéramos que recomendar una configuración con una compensación razonable en cuanto a rendimiento y confiabilidad, sería la siguiente:
Estas son únicamente unas líneas generales; las empresas dedicadas a ello generalmente ejecutan ASP con un nivel de aislamiento medio o alto, mientras que los servidores Web de un único propósito pueden ejecutarse con un aislamiento bajo. Analice las compensaciones y decida la configuración que se ajusta en mayor medida a sus necesidades. Sugerencia 10: Utilizar Option ExplicitUtilice Quizás algo aún más importante, resulta que las variables
declaradas son más rápidas que las no declaradas. El tiempo de ejecución
de las secuencias hace referencia por nombre a las variables no
declaradas cada vez que se utilizan. A las variables declaradas, por
otra parte, se asigna un ordinal ya sea durante el tiempo de compilación
o el de ejecución. Por consiguiente, el ordinal hace referencia a las
variables declaradas. Debido a que Sugerencia 11: Utilizar variables locales en las subrutinas y las funcionesLas variables locales son aquellas que se declaran con las subrutinas y las funciones. Dentro de una subrutina o función, el acceso a una variable local es mucho más rápido que a una global. La utilización de las variables también tiende a hacer que el código presente una mayor claridad, por lo que se recomienda su uso siempre que sea posible. Sugerencia 12: Copiar datos utilizados frecuentemente en las variables de la secuenciaCuando se tiene acceso a los objetos COM en ASP, se deben copiar los datos de objetos utilizados frecuentemente en las variables de la secuencia. De esta forma se reduce el número de llamadas a los métodos COM, que resultan relativamente costosos comparados con el acceso a las variables de las secuencias. Obtener acceso a los objetos Collection y Dictionary reduce el número de costosas consultas que es preciso llevar a cabo. Por regla general, si se desea obtener acceso a datos de objetos más
de una vez, éstos se deben introducir en una variable de secuencia. Los
protagonistas principales a los que va dirigida esta optimización son
las variables de solicitud (Form y QueryString). Por ejemplo, puede que
su sitio pase una variable QueryString denominada UserID. Supongamos que
se hace referencia a UserID una docena de veces en una página concreta.
En lugar de llamar a En la práctica, el acceso a las propiedades o métodos COM puede resultar costoso en apariencia. A continuación se proporciona un ejemplo de código muy común (desde el punto de vista sintáctico): Foo.bar.blah.baz = Foo.bar.blah.qaz(1) If Foo.bar.blah.zaq = Foo.bar.blah.abc Then ' ... Esto es lo que sucede cuando se ejecuta el código:
Como se puede ver, se trata de un sistema terriblemente ineficaz (y lento). La forma rápida de escribir el código en VBScript es: Set myobj = Foo.bar.blah ' resolver blah UNA VEZ Myobj.baz = myobj.qaz(1) If Myobj.zaq = Myobj.abc Then '... Si se utiliza VBScript 5.0 o
posterior, se puede escribir utilizando la instrucción With Foo.bar.blah .baz = .qaz(1) If .zaq = .abc Then '... ... End With Tenga en cuenta que esta sugerencia también se puede aplicar a la programación en VB. Sugerencia 13: Evitar redimensionar las matricesSe debe intentar evitar la redimensión de las matrices con El código que aparece a continuación muestra la utilización
gratuita de <% Dim MyArray() Redim MyArray(2) MyArray(0) = "hola" MyArray(1) = "adiós" MyArray(2) = "hasta pronto" ... ' otro código en el que es necesario más espacio, entonces ... Redim Preserve MyArray(5) MyArray(3) = "más material" MyArray(4) = "aún más material" MyArray(5) = "todavía mucho más material" %> Es mucho más fácil dimensionar la matriz con Sugerencia 14: Utilizar el búfer de respuestaSe puede almacenar en búfer la salida de una página completa activando la opción de “búfer de respuesta”. Se minimiza la cantidad de veces que es necesario escribir en el explorador y se mejora el rendimiento general. Cada escritura supone una sobrecarga (tanto en IIS como en la cantidad de datos que se envían), por tanto, cuantas menos escrituras sea preciso realizar, mejor. TCP/IP ofrece mejores resultados cuando se envían varios bloques de datos grandes que cuando se deben enviar muchos bloques pequeños debido al inicio lento (en inglés) y al algoritmo de Nagle (en inglés) (empleados para reducir las sobrecarga de la red). Existen dos maneras de activar el búfer de respuesta. En primer lugar, se puede activar para toda la aplicación utilizando para ello el Administrador de servicios de Internet. Se trata del enfoque recomendado, por lo que el búfer de respuesta se encuentra activado de forma predeterminada en las aplicaciones ASP en IIS 4.0 y IIS 5.0. En segundo lugar, página a página; es decir, se puede activar el búfer de respuesta introduciendo la siguiente línea de código en la parte superior de la página ASP: <% Response.Buffer = True %> Esta línea de código debe ejecutarse antes de que se escriba
cualquier dato de repuesta en el explorador (es decir, antes de que
aparezca el HTML en la secuencia ASP y antes de que se envíe cualquier
cookie con la colección Response.FlushUno de los problemas que se plantean con el búfer de respuesta es
los usuarios perciben que la respuesta que obtienen de las páginas ASP
es menor (aunque el tiempo global de respuesta se haya mejorado) ya que
deben esperar a que se genere toda la página antes de poder ver algo.
En el caso de las páginas que tardan en cargarse, se puede activar el búfer
de respuesta con (Es importante señalar que en el ejemplo anterior de una tabla de
1.000 filas, muchos exploradores no empezarán a cargar la tabla hasta
que vean la etiqueta de cierre </table>. Compruebe los
exploradores para obtener información sobre compatibilidad. Para
solucionar este problema, intente dividir la tabla en varias más pequeñas
con menos filas cada una de ellas y llame a Otro de los problemas más comunes que presenta el búfer de
respuesta es que puede utilizar gran parte de la memoria del servidor
cuando genera páginas muy extensas. Dejando a un lado la cuestión de
si es recomendable o no generar páginas extensas, también se puede
hacer frente a este problema utilizando
Nota: Para cualquier consulta u opinión sobre este articulo puedes usar los foros
AspTutor lo hacemos entre todos ¿Como vas a colaborar hoy? |
Descargas
de manuales¦ Ejemplos
de código ¦ Artículos
mas visitados ¦ Envía
tu articulo ¦ Foros ¦ |
© 2001-Hasta hoy Pedro Rufo Martín contactar |
|