Consideraciones de rendimiento al usar el motor de reglas
Este tema trata sobre el rendimiento del motor de reglas en varios escenarios y con diferentes valores en los parámetros de configuración o ajuste.
Tipos de hechos
El motor de reglas tarda menos en obtener acceso a los hechos .NET que a los hechos XML y de base de datos. Si puede elegir entre usar hechos .NET, XML o de base de datos en una directiva, debería optar más bien por usar hechos .NET para obtener un mejor rendimiento.
Enlace de tabla de datos frente a enlace de conexión de datos
Cuando el tamaño del conjunto de datos es pequeño (menos de aproximadamente 10 filas), el enlace TypedDataTable funciona mejor que el enlace DataConnection . Cuando el conjunto de datos es grande (mayor o igual que aproximadamente 10 filas), el enlace DataConnection funciona mejor que el enlace TypedDataTable . Por lo tanto, debe decidir si se debe usar el enlace DataConnection o el enlace TypedDataTable en función del tamaño estimado del conjunto de datos.
Administradores de almacenes de datos
Puede escribir un recuperador de hechos: un objeto que implementa métodos estándar y que normalmente los usa para proporcionar hechos a largo plazo y cambiar lentamente al motor de reglas antes de ejecutar la directiva. El motor almacena estos datos en caché y los utiliza en varios ciclos de ejecución. En lugar de enviar un hecho estático o casi estático cada vez que invoque el motor de reglas, debería crear un administrador de almacenes de datos que envíe el hecho la primera vez y, a continuación, lo actualice en la memoria solo cuando se necesite.
Prioridad de las reglas
La configuración de prioridad de una regla puede oscilar en cualquier lado de 0, con números mayores con mayor prioridad. Las acciones se ejecutan en orden desde prioridad más alta a prioridad más baja. Cuando la directiva implementa el comportamiento de encadenamiento de reenvío mediante llamadas Assert/Update , el encadenamiento se puede optimizar mediante la configuración de prioridad. Por ejemplo, supongamos que Rule2 tiene una dependencia de un valor establecido por Rule1. Conceder a Rule1 una prioridad más alta significa que Rule2 solo se ejecutará después de que Rule1 se active y actualice el valor. Por el contrario, si a Rule2 se le da una prioridad más alta, se puede activar una vez y, a continuación, volver a activar después de que Rule1 se active y actualice el hecho de que Rule2 está usando en una condición. Esto puede producir resultados correctos o no, pero está claro que una doble activación repercute más sobre el rendimiento que una sola.
Llamadas a Update
La función Update actualiza un hecho que existe en la memoria de trabajo del motor de reglas y hace que se vuelvan a evaluar todas las reglas que usan el hecho actualizado en condiciones. Las llamadas de función de actualización pueden ser costosas, especialmente si es necesario volver a evaluar muchas reglas debido a la actualización de los hechos. Hay situaciones en las que es posible evitar que vuelvan a evaluarse las reglas. Por ejemplo, imagine las siguientes reglas:
Regla 1:
IF PurchaseOrder.Amount > 5
THEN StatusObj.Flag = true; Update(StatusObj)
Regla 2:
IF PurchaseOrder.Amount <= 5
THEN StatusObj.Flag = false; Update(StatusObj)
Todas las reglas restantes de la directiva usan StatusObj.Flag en sus condiciones. Por lo tanto, cuando se llama a Update en el objeto StatusObj , se volverán a evaluar todas las reglas. Sea cual sea el valor del campo Importe , todas las reglas excepto Rule1 y Rule2 se evalúan dos veces, una vez antes de la llamada a Update y una vez después de la llamada a Update .
En su lugar, podría establecer el valor del campo de marca en false antes de invocar la directiva y, a continuación, usar solo Rule1 en la directiva para establecer la marca. En este caso, solo se llama a Update si el valor del campo Importe es mayor que 5 y no se llama a Update si la cantidad es menor o igual que 5. Por lo tanto, todas las reglas excepto Rule1 y Rule2 solo se evalúan dos veces si el valor del campo Importe es mayor que 5.
Uso de operadores O lógicos
El motor de reglas está optimizado para ejecutar operadores AND lógicos y reconstruye la regla que analiza en un formato normal disjuntivo para que el operador OR solo se use en el nivel superior. El uso de un número creciente de operadores OR lógicos en condiciones crea permutaciones adicionales que expanden la red de análisis del motor de reglas y puede tardar mucho tiempo en normalizar la regla. La lista siguiente contiene posibles soluciones para este problema.
Modifique la regla para que esté en forma normal disjuntiva para que el operador OR solo esté en el nivel superior. Tenga en cuenta que desarrollar una regla en forma disyuntiva normal en el Compositor de reglas de negocio puede ser complicado. Quizás desee considerar la posibilidad de crear la regla mediante programación.
Desarrolle un componente auxiliar que realice las operaciones OR y devuelva un valor booleano y use el componente en la regla.
Considere la posibilidad de dividir la regla en varias y que una regla ejecutada previamente compruebe un conjunto de marcas o bien usar un objeto impuesto por una regla ejecutada previamente, tal como se muestra en los ejemplos siguientes:
Regla 1: IF (a == 1 O a == 3) THEN b = true
Regla 2: si (b == true) THEN ...
Regla 1: IF (a == 1 O a == 3) THEN assert(new c())
Regla 2: IF (c.flag == true) THEN ...
Configuración de almacenamiento en caché
El motor de reglas usa dos cachés. La primera se encuentra en el servicio de actualización y la segunda en cada uno de los procesos de BizTalk. La primera vez que se usa una directiva, el proceso de BizTalk solicita la información de la directiva al servicio de actualización. El servicio de actualización recupera la información de la directiva desde la base de datos del motor de reglas, la almacena en caché y devuelve la información al proceso de BizTalk. El proceso de BizTalk crea un objeto de directiva basado en esa información y lo almacena en una caché cuando la instancia del motor de reglas completa la ejecución de la directiva. Cuando se vuelve a invocar la misma directiva, el proceso de BizTalk usa nuevamente el objeto de la directiva desde la caché si hay alguno disponible.
De igual modo, si el proceso de BizTalk solicita la información acerca de una directiva al servicio de actualización, éste busca en primer lugar la información de la directiva en su caché. El servicio de actualización también comprueba cada 60 segundos si ha habido actualizaciones de la directiva que está en la base de datos. Si hay actualizaciones, el servicio de actualización recupera la información y almacena en caché la información actualizada.
Hay tres parámetros de optimización para el motor de reglas relacionados con estas memorias caché: CacheEntries, CacheTimeout y PollingInterval. Se pueden especificar los valores de estos parámetros tanto en el Registro como en un archivo de configuración.
El valor de CacheEntries es el número máximo de entradas de la memoria caché. El valor predeterminado de CacheEntries es 32. Es posible que desee aumentar el valor del parámetro CacheEntries para mejorar el rendimiento en algunos casos. Por ejemplo, imagine que está usando 40 directivas de forma repetida. En este caso, es posible que desee aumentar el valor de CacheEntries a 40 para mejorar el rendimiento. Con ello permitirá al servicio de actualización almacenar los detalles de hasta 40 directivas en la memoria caché. Y también hará que el servicio de BizTalk almacene hasta 40 instancias de directiva en la memoria caché. Puede haber más de una instancia de una directiva en la caché del servicio de BizTalk.
El valor de CacheTimeout es el tiempo (en segundos) para que las entradas agoten la antigüedad de la caché del servicio de actualización. En otras palabras, el valor CacheTimeout hace referencia a cuánto tiempo se mantiene una entrada de caché para una directiva en la memoria caché si no hay referencias a ella. El valor predeterminado de CacheTimeout es de 3600 segundos (una hora). Esto quiere decir que, si no se hace referencia a la entrada de caché en el transcurso de una hora, se borrará. En algunos casos, es posible que desee aumentar el valor de CacheTimeout para mejorar el rendimiento. Por ejemplo, suponga que se invoca la directiva cada dos horas. Puede mejorar el rendimiento de la ejecución de la directiva aumentando el valor del parámetro CacheTimeout a un valor superior a dos horas.
El parámetro PollingInterval para el motor de reglas define el tiempo en segundos para el intervalo en el que el servicio Update comprueba si hay actualizaciones en la base de datos del motor de reglas. El valor predeterminado para el parámetro PollingInterval es de 60 segundos (un minuto). Si sabe que las directivas no se actualizan o lo hacen con poca frecuencia, puede incrementar este valor para mejorar el rendimiento.
SideEffects (propiedad)
Las clases ClassMemberBinding, DatabaseColumnBinding y XmlDocumentFieldBinding tienen una propiedad denominada SideEffects. Esta propiedad determina si el valor del campo, de la columna o del miembro enlazados se ha almacenado en caché. El valor predeterminado de la propiedad SideEffects en las clases DatabaseColumnBinding y XmlDocumentFieldBinding es false. El valor predeterminado de la propiedad SideEffects de la clase ClassMemberBinding es true. Por lo tanto, cuando se obtiene acceso por segunda vez (o más tarde dentro de la directiva) a un campo de un documento XML o a una columna de una tabla de una base de datos, su valor se recupera desde la caché. Sin embargo, cuando se obtiene acceso por segunda vez (o posteriormente) a un miembro de un objeto .NET, el valor se recupera desde el objeto .NET y no desde la caché. Establecer la propiedad SideEffects de un classMemberBinding de .NET en false mejorará el rendimiento porque el valor del campo se recupera de la memoria caché desde la segunda vez en adelante. Tan solo se puede hacer esto mediante programación. La herramienta Business Rule Composer no expone la propiedad SideEffects .
Instances y Selectivity
Las clases XmlDocumentBinding, ClassBinding y DatabaseBinding tienen dos propiedades: Instances y Selectivity. El valor de Instances es el número esperado de instancias de la clase en memoria de trabajo. El valor de Selectivity es el porcentaje de las instancias de clase que pasarán correctamente las condiciones de la regla. El motor de reglas usa estos valores para optimizar la evaluación de condiciones de modo que se utilice primero el menor número de instancias posible en las evaluaciones de condiciones y posteriormente se usen las instancias restantes. Si tiene conocimiento previo del número de instancias del objeto, establecer la propiedad Instances en ese valor mejoraría el rendimiento. Del mismo modo, si tiene conocimiento previo del porcentaje de estos objetos que pasan las condiciones, establecer la propiedad Selectivity en ese valor mejoraría el rendimiento. Tan solo se pueden establecer los valores de estos parámetros mediante programación. La herramienta Compositor de reglas de negocio no los expone.