estoy cavando en C# código fuente recientemente.un problema de aplicación de F # Sec
en Seq.fs:
// Binding.
//
// We use a type defintion to apply a local dynamic optimization.
// We automatically right-associate binding, i.e. push the continuations to the right.
// That is, bindG (bindG G1 cont1) cont2 --> bindG G1 (cont1 o cont2)
// This makes constructs such as the following linear rather than quadratic:
//
// let rec rwalk n = { if n > 0 then
// yield! rwalk (n-1)
// yield n }
Después de ver el código anterior, he probado dos código:
let rec rwalk n = seq { if n > 0 then
yield n
yield! rwalk (n-1)
}
y
let rec rwalk n = seq { if n > 0 then
yield! rwalk (n-1)
yield n
}
me encontré con la primera es muy rápido , mientras que el segundo es muy lento. Si n = 10000, cuesta 3 segundos en mi máquina generar esta secuencia, por lo tanto, tiempo cuadrático.
El tiempo cuadrática es razonable, como por ejemplo,
seq { yield! {1; 2; ...; n-1}; yield n }
se traduce en
Seq.append {1; 2; ...; n-1} {n}
Esta operación de anexión debe tomar el tiempo lineal, supongo. Mientras está en el primer código, la operación de agregar es así: seq { yield n; yield! {n-1; n-2; ...; 1} }
, que cuesta tiempo constante.
Los comentarios de los códigos dicen que es linear
(tal vez esto no es lineal del tiempo lineal). Quizás esto linear
se relaciona con el uso de implementación personalizada para la secuencia en lugar de la expresión de cálculo Moand/F # (como se menciona en la especificación F #; sin embargo, la especificación no menciona el motivo para hacerlo ...).
Podría alguien aclarar la falta de claridad en esta lista? ¡Muchas gracias!
(ps porque se trata de un diseño de lenguaje y problemas de optimización, que la etiqueta Haskell también se adjunta para ver si las personas no tienen puntos de vista.)
+1 para excavar a través del código fuente – Brian