Compartir a través de


Funciones insertadas

Las funciones insertadas son funciones que se integran directamente en el código de llamada.

Uso de funciones insertadas

Cuando se usan parámetros de tipo estático, las funciones parametrizadas por parámetros de tipo deben estar insertadas. Esto garantiza que el compilador pueda resolver estos parámetros de tipo. Cuando se usan parámetros de tipo genérico normal, no hay ninguna restricción de este tipo.

Aparte de habilitar el uso de restricciones de miembro, las funciones insertadas pueden resultar útiles para optimizar el código. Sin embargo, el uso excesivo de funciones insertadas puede hacer que el código sea menos resistente a los cambios en las optimizaciones del compilador y la implementación de funciones de biblioteca. Por este motivo, debe evitar el uso de funciones insertadas para la optimización a menos que haya probado todas las demás técnicas de optimización. La creación de una función o método insertada a veces puede mejorar el rendimiento, pero eso no siempre es el caso. Por lo tanto, también debe usar medidas de rendimiento para comprobar que, de hecho, hacer que cualquier función determinada insertada tenga un efecto positivo.

El inline modificador se puede aplicar a funciones en el nivel superior, en el nivel de módulo o en el nivel de método de una clase.

En el ejemplo de código siguiente se muestra una función insertada en el nivel superior, un método de instancia insertado y un método estático insertado.

let inline increment x = x + 1
type WrapInt32() =
    member inline this.incrementByOne(x) = x + 1
    static member inline Increment(x) = x + 1

Funciones insertadas y inferencia de tipos

La presencia de afecta a la inferencia de inline tipos. Esto se debe a que las funciones insertadas pueden tener parámetros de tipo resueltos estáticamente, mientras que las funciones no insertadas no pueden. En el ejemplo de código siguiente se muestra un caso en inline el que resulta útil porque usa una función que tiene un parámetro de tipo resuelto estáticamente, el operador de float conversión.

let inline printAsFloatingPoint number =
    printfn "%f" (float number)

Sin el modificador , la inline inferencia de tipos obliga a la función a tomar un tipo específico, en este caso int. Pero con el inline modificador , la función también se deduce para tener un parámetro de tipo resuelto estáticamente. Con el inline modificador , se deduce que el tipo es el siguiente:

^a -> unit when ^a : (static member op_Explicit : ^a -> float)

Esto significa que la función acepta cualquier tipo que admita una conversión a float.

InlineIfLambda

El compilador de F# incluye un optimizador que realiza la inserción de código. El InlineIfLambda atributo permite que el código indique opcionalmente que, si se determina que un argumento es una función lambda, ese argumento siempre debe estar insertado en los sitios de llamada. Para obtener más información, consulte F# RFC FS-1098.

Por ejemplo, considere la siguiente iterateTwice función para recorrer una matriz:

let inline iterateTwice ([<InlineIfLambda>] action) (array: 'T[]) =
    for i = 0 to array.Length-1 do
        action array[i]
    for i = 0 to array.Length-1 do
        action array[i]

Si el sitio de llamada es:

let arr = [| 1.. 100 |]
let mutable sum = 0
arr  |> iterateTwice (fun x ->
    sum <- sum + x)

Después de insertar y otras optimizaciones, el código se convierte en:

let arr = [| 1..100 |]
let mutable sum = 0
for i = 0 to arr.Length - 1 do
    sum <- sum + arr[i] 
for i = 0 to arr.Length - 1 do
    sum <- sum + arr[i] 

Esta optimización se aplica independientemente del tamaño de la expresión lambda implicada. Esta característica también se puede usar para implementar transformaciones similares y desenrollamiento de bucles de forma más confiable.

Se puede activar una advertencia de participación (/warnon:3517 o propiedad <WarnOn>3517</WarnOn>) para indicar lugares en el código donde InlineIfLambda los argumentos no están enlazados a expresiones lambda en los sitios de llamada. En situaciones normales, esta advertencia no debe estar habilitada. Sin embargo, en ciertos tipos de programación de alto rendimiento, puede ser útil asegurarse de que todo el código está insertado y aplanado.

Consulte también