Я хочу написать большой кусок кода С#, используя неизменяемый F #. Это монитор устройства, и текущая реализация работает, постоянно получая данные из последовательного порта и обновляя переменные-члены на основе новых данных. Я бы хотел передать это на F # и получить преимущества неизменных записей, но мой первый выстрел по реализации концепции доказательств очень медленный.
open System
open System.Diagnostics
type DeviceStatus = { RPM : int;
Pressure : int;
Temperature : int }
// I'm assuming my actual implementation, using serial data, would be something like
// "let rec UpdateStatusWithSerialReadings (status:DeviceStatus) (serialInput:string[])".
// where serialInput is whatever the device streamed out since the previous check: something like
// ["RPM=90","Pres=50","Temp=85","RPM=40","Pres=23", etc.]
// The device streams out different parameters at different intervals, so I can't just wait for them all to arrive and aggregate them all at once.
// I'm just doing a POC here, so want to eliminate noise from parsing etc.
// So this just updates the status RPM i times and returns the result.
let rec UpdateStatusITimes (status:DeviceStatus) (i:int) =
match i with
| 0 -> status
| _ -> UpdateStatusITimes {status with RPM = 90} (i - 1)
let initStatus = { RPM = 80 ; Pressure = 100 ; Temperature = 70 }
let stopwatch = new Stopwatch()
stopwatch.Start()
let endStatus = UpdateStatusITimes initStatus 100000000
stopwatch.Stop()
printfn "endStatus.RPM = %A" endStatus.RPM
printfn "stopwatch.ElapsedMilliseconds = %A" stopwatch.ElapsedMilliseconds
Console.ReadLine() |> ignore
Это работает примерно на 1400 мс на моей машине, тогда как эквивалентный код С# (с изменяемыми переменными-членами) работает примерно в 310 мс. Есть ли способ ускорить это, не теряя неизменности? Я надеялся, что компилятор F # заметил бы, что initStatus и все промежуточные переменные состояния никогда не использовались повторно, и, таким образом, просто мутировать эти записи за сценой, но я думаю, что нет.