Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Funções embutidas são funções integradas diretamente ao código de chamada.
Usando funções embutidas
Quando você usa parâmetros de tipo estático, todas as funções parametrizadas por parâmetros de tipo devem estar embutidas. Isso garante que o compilador possa resolver esses parâmetros de tipo. Quando você usa parâmetros de tipo genérico comuns, não há essa restrição.
Além de habilitar o uso de restrições de membro, as funções embutidas podem ser úteis para otimizar o código. No entanto, o uso excessivo de funções embutidas pode fazer com que seu código seja menos resistente a alterações nas otimizações do compilador e à implementação de funções de biblioteca. Por esse motivo, você deve evitar o uso de funções embutidas para otimização, a menos que tenha tentado todas as outras técnicas de otimização. Fazer uma função ou método embutido às vezes pode melhorar o desempenho, mas nem sempre é o caso. Portanto, você também deve usar medidas de desempenho para verificar se fazer qualquer função embutida de fato tem um efeito positivo.
O inline modificador pode ser aplicado a funções no nível superior, no nível do módulo ou no nível do método em uma classe.
O exemplo de código a seguir ilustra uma função embutida no nível superior, um método de instância embutida e um método estático embutido.
let inline increment x = x + 1
type WrapInt32() =
member inline this.incrementByOne(x) = x + 1
static member inline Increment(x) = x + 1
Funções embutidas e inferência de tipo
A presença de inline afeta a inferência de tipo. Isso ocorre porque as funções embutidas podem ter parâmetros de tipo resolvidos estaticamente, enquanto as funções não embutidas não podem. O exemplo de código a seguir mostra um caso em que inline é útil porque você está usando uma função que tem um parâmetro de tipo estaticamente resolvido, o operador de float conversão.
let inline printAsFloatingPoint number =
printfn "%f" (float number)
Sem o inline modificador, a inferência de tipo força a função a usar um tipo específico, nesse caso int. Mas com o inline modificador, a função também é inferida para ter um parâmetro de tipo estaticamente resolvido. Com o inline modificador, o tipo é inferido para ser o seguinte:
^a -> unit when ^a : (static member op_Explicit : ^a -> float)
Isso significa que a função aceita qualquer tipo que dê suporte a uma conversão para flutuar.
InlineIfLambda
O compilador F# inclui um otimizador que executa a inlining of code. O InlineIfLambda atributo permite que o código indique opcionalmente que, se um argumento for determinado como uma função lambda, esse argumento deve ser sempre sublinhado em sites de chamada. Para obter mais informações, consulte F# RFC FS-1098.
Por exemplo, considere a seguinte iterateTwice função para percorrer uma 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]
Se o site de chamada for:
let arr = [| 1.. 100 |]
let mutable sum = 0
arr |> iterateTwice (fun x ->
sum <- sum + x)
Depois de sublinhar e outras otimizações, o código se torna:
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]
Essa otimização é aplicada independentemente do tamanho da expressão lambda envolvida. Esse recurso também pode ser usado para implementar o cancelamento de loop e transformações semelhantes de forma mais confiável.
Um aviso de aceitação (/warnon:3517 ou propriedade <WarnOn>3517</WarnOn>) pode ser ativado para indicar locais em seu código InlineIfLambda em que os argumentos não estão associados a expressões lambda em sites de chamada. Em situações normais, esse aviso não deve ser habilitado. No entanto, em determinados tipos de programação de alto desempenho, pode ser útil garantir que todo o código seja embutido e achatado.