Functional programming 同一函数的执行是否比将结果关联到变量差两倍?

Functional programming 同一函数的执行是否比将结果关联到变量差两倍?,functional-programming,ocaml,caml-light,Functional Programming,Ocaml,Caml Light,有人告诉我,就性能而言,第一段代码比第二段代码差 但是,老实说,我不知道如果最后还是打了同样的电话,他们会有什么不同。 我错过什么了吗 第一个显式调用示例: #let rec max l = match l with x::[]->x | x::xs -> if(x > max xs) then x else max xs;; 使用变量的第二个示例: #let rec max l = match l with x::[]->x | x::xs -> l

有人告诉我,就性能而言,第一段代码比第二段代码差

但是,老实说,我不知道如果最后还是打了同样的电话,他们会有什么不同。 我错过什么了吗

第一个显式调用示例:

#let rec max l =
match l with
x::[]->x
| x::xs -> if(x > max xs) 
     then x else max xs;;
使用变量的第二个示例:

#let rec max l =
match l with
x::[]->x
| x::xs -> let m = max xs
in
if (x>m) then x else m;;

关键是ocaml编译器不知道
max xs
max xs
是同一件事,因此您的第一个示例相当于:

let rec max l =
  match l with
   | x::[]-> x
   | x::xs ->
     let m1 = max xs in (* first call *)
     if (x > m1) then
       x
     else
       let m2 = max xs in
       m2 (* second call *)
;;
只进行一次调用是一种有效的优化,但在一般情况下是不正确的。例如:

let f () =
  print_endline "hello";
  print_endline "hello";
  3
不等同于:

let g () =
  let x = print_endline "hello" in
  x;
  x;
  3

关键是ocaml编译器不知道
max xs
max xs
是同一件事,因此您的第一个示例相当于:

let rec max l =
  match l with
   | x::[]-> x
   | x::xs ->
     let m1 = max xs in (* first call *)
     if (x > m1) then
       x
     else
       let m2 = max xs in
       m2 (* second call *)
;;
只进行一次调用是一种有效的优化,但在一般情况下是不正确的。例如:

let f () =
  print_endline "hello";
  print_endline "hello";
  3
不等同于:

let g () =
  let x = print_endline "hello" in
  x;
  x;
  3

什么确切地包含或与m相关?
m
是对
max xs
的计算结果,它不是缩写。每次使用相同的
xs
计算
max xs
,都会得到相同的结果。是的,知道list
xs
和元素
x
中包含的最大值,
max
计算列表
x::xs
中包含的最大值。但是您所做的是在相同的递归级别上调用两次
(max xs)
。调用
max xs
的两个位置的
xs
是否不同?不,是同一张单子。因此,
max xs
将给出相同的结果。只有知道这个递归结果后,才能确定返回哪个值(x或该值,取最大值)。@coredump哦,是的,现在我明白了。习惯命令式范式会使适应函数式编程变得有点复杂。Bahut dhanyavaad解释一下,我的朋友。到底是什么包含了m或与m相关?
m
是对
max xs
的计算结果,它不是缩写。每次你用相同的
xs
计算
max xs
,你都会得到相同的结果。是的,知道列表
xs
中包含的最大值和元素
x
max
计算列表
x::xs
中包含的最大值。但是您所做的是在相同的递归级别上调用两次
(max xs)
。调用
max xs
的两个位置的
xs
是否不同?不,是同一张单子。因此,
max xs
将给出相同的结果。只有知道这个递归结果后,才能确定返回哪个值(x或该值,取最大值)。@coredump哦,是的,现在我明白了。习惯命令式范式会使适应函数式编程变得有点复杂。巴胡特·达尼亚瓦德(Bahut dhanyavaad)的解释,我的朋友。为什么人们投票反对?当然,这可能是一个愚蠢的错误——一旦您看到它——理解代码的人会看到它,但OP看不到它。无知并不是投反对票的理由;不做家庭作业是错误的。但这并不是说OP没有看,或者没有清楚地解释问题是什么,或者没有展示相关的工作。Afaics,OP做了家庭作业,但就是没有必要的洞察力,不管它有多小。也许有理由不投赞成票,但也有理由不投反对票。在目前的答案之后进行的讨论表明,误解更深。@Mars许多人可能觉得这些问题站不住脚,或者太新手,所以决定否决投票。。。他们完全有权。谢谢@user9193072。这就是我想知道的。我个人不同意这一政策,但也有细微差别。应该欢迎那些真诚地尝试找出答案并证明自己找到了答案的新手。我同意有些问题,任何人,无论多么新,都应该花额外的20秒来看看答案,或者在问任何问题之前真正学习语言的基本知识。这些人还没有做出真诚的尝试来解决这个问题。这似乎不是那种情况。我想,理智的人可能不同意这一点。除非我不讲道理。为什么人们会投反对票?当然,这可能是一个愚蠢的错误——一旦您看到它——理解代码的人会看到它,但OP看不到它。无知并不是投反对票的理由;不做家庭作业是错误的。但这并不是说OP没有看,或者没有清楚地解释问题是什么,或者没有展示相关的工作。Afaics,OP做了家庭作业,但就是没有必要的洞察力,不管它有多小。也许有理由不投赞成票,但也有理由不投反对票。在目前的答案之后进行的讨论表明,误解更深。@Mars许多人可能觉得这些问题站不住脚,或者太新手,所以决定否决投票。。。他们完全有权。谢谢@user9193072。这就是我想知道的。我个人不同意这一政策,但也有细微差别。应该欢迎那些真诚地尝试找出答案并证明自己找到了答案的新手。我同意有些问题,任何人,无论多么新,都应该花额外的20秒来看看答案,或者在问任何问题之前真正学习语言的基本知识。这些人还没有做出真诚的尝试来解决这个问题。这似乎不是那种情况。我想,理智的人可能不同意这一点。除非我不讲理。