// Печать списка
let rec printList1 list =
match list with
| [] -> printf "\n"
| h::t -> printf "%A " h
printList1 t
let rec printList2 list =
match list with
| [] -> printf "\n"
| _ -> printf "%A " list.Head
printList2 list.Tail
F# - какой вариант быстрее?
Какая из этих двух функций лучше с точки зрения быстродействия? Что лучше использовать - декомпозицию :: или свойства? И как правильнее с точки зрения функционального подхода?
Код:
Похожий вопрос: использование кортежа ухудшит производительность или нет? Я понимаю, что вариант без кортежа функциональнее: можно каррирование применить.
Код:
// Возведение в степень
let rec pow1 x n =
if n = 1 then x
else x * pow1 x (n - 1)
let rec pow2(x, n) =
if n = 1 then x
else x * pow2(x, n - 1)
let rec pow1 x n =
if n = 1 then x
else x * pow1 x (n - 1)
let rec pow2(x, n) =
if n = 1 then x
else x * pow2(x, n - 1)
Уточню: интересует производительность не в данной конкретной реализации языка (это я и сам могу замерить время выполнения), а такой подход, который будет лучше в общем случае.
Цитата:
Какая из этих двух функций лучше с точки зрения быстродействия? Что лучше использовать - декомпозицию :: или свойства? И как правильнее с точки зрения функционального подхода?
List.iter есть же, вообще для таких вещей есть iter во всех коллекциях F#:
Цитата:
> let l = [1;2;3];;
val l : int list = [1; 2; 3]
> List.iter (fun x -> printfn "%A" x) l;;
1
2
3
val it : unit = ()
val l : int list = [1; 2; 3]
> List.iter (fun x -> printfn "%A" x) l;;
1
2
3
val it : unit = ()
По твоему коду:
Код:
// Печать списка
let rec printList1 list =
match list with
| [] -> printf "\n"
| h::t -> printf "%A " h
printList1 t
let rec printList2 list =
match list with
| [] -> printf "\n"
| _ -> printf "%A " list.Head
printList2 list.Tail
let rec printList1 list =
match list with
| [] -> printf "\n"
| h::t -> printf "%A " h
printList1 t
let rec printList2 list =
match list with
| [] -> printf "\n"
| _ -> printf "%A " list.Head
printList2 list.Tail
Второй вариант получше в данном случае, т.к. под h и t будут сделаны отдельные переменные, а list.Head и list.Tail - вызов методов объекта без объявления новых переменных. Посмотри выхлоп рефлектора, такой простой код F# он более менее транслирует в C#.
Цитата:
Уточню: интересует производительность не в данной конкретной реализации языка (это я и сам могу замерить время выполнения), а такой подход, который будет лучше в общем случае.
На счёт производительности не скажу - не знаю. А вот с точки зрения места применения - кортеж нужно использовать в том случае, если нужно вызывать F# функции из C#, т.к. C# функция это(схематично) (X) -> Y.
п.с. правильнее pow сделать так:
Код:
let pow x n =
let rec _pow x n count =
if n = 1 then count*x
else _pow x (n-1) (x*count)
_pow x n 1
let rec _pow x n count =
if n = 1 then count*x
else _pow x (n-1) (x*count)
_pow x n 1
В этом случае рекурсия будет хвостовой и раскроется в цикл.