- 浏览: 1400196 次
- 性别:
- 来自: 火星
文章分类
最新评论
-
aidd:
内核处理time_wait状态详解 -
ahtest:
赞一下~~
一个简单的ruby Metaprogram的例子 -
itiProCareer:
简直胡说八道,误人子弟啊。。。。谁告诉你 Ruby 1.9 ...
ruby中的类变量与类实例变量 -
dear531:
还得补充一句,惊群了之后,数据打印显示,只有一个子线程继续接受 ...
linux已经不存在惊群现象 -
dear531:
我用select试验了,用的ubuntu12.10,内核3.5 ...
linux已经不存在惊群现象
今天看 python in nutshell 时看到了这段
Reader who are familiar Lisp, Scheme, or functional-programming languages must in particular be aware that Python does not implement the optimization of "tail-call elimination," which is so important in these languages. In Python, any call, recursive or not, has the same cost in terms of both time and memory space, dependent only on the number of arguments: the cost does not change, whether the call is a "tail-call" (meaning that the call is the last operation that the caller executes) or any other, nontail call.
说python中不能实现optimization of "tail-call elimination,"可是我google中搜索了一下发现了这个
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/474088
可是由于不太了解functional-programming 所以the optimization of "tail-call elimination" 也不知道确切的意思,所以也不知道下面的代码写的对不对。
下面的代码是上面的链接里面的那个人写的.
哦,原来这样,为什么不鼓励写loop呢,还有就是python中的异常开销是不是不大?
因为传统上循环总需要个计数器,也就是side effect拉。所以FP鼓励用递归或list comprehension,有点洁癖之嫌吧?
至少有一个最新的理由:
函数式的列表操作(map/reduce/filter)是可以拆分的
比如reduce,你可以把一个大列表分成几个小列表,分别对它们做reduce,得到的结果放进同一个列表再做reduce,效果是一样的
map,更是如此
filter,同样
所以你就可以把“分解成小列表的操作”放在几个核上运行
这样就可以充分利用多核的计算能力
大部分情况都如你所说,不过也有例外,比如前后依赖的lazy list:
fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]
另外我觉得这是实现细节,聪明点的编译器也许能辨别能否把loop拆开来并行,比如考虑矩阵相乘操作。
哦,原来这样,为什么不鼓励写loop呢,还有就是python中的异常开销是不是不大?
因为传统上循环总需要个计数器,也就是side effect拉。所以FP鼓励用递归或list comprehension,有点洁癖之嫌吧?
至少有一个最新的理由:
函数式的列表操作(map/reduce/filter)是可以拆分的
比如reduce,你可以把一个大列表分成几个小列表,分别对它们做reduce,得到的结果放进同一个列表再做reduce,效果是一样的
map,更是如此
filter,同样
所以你就可以把“分解成小列表的操作”放在几个核上运行
这样就可以充分利用多核的计算能力
哦,原来这样,为什么不鼓励写loop呢,还有就是python中的异常开销是不是不大?
因为传统上循环总需要个计数器,也就是side effect拉。所以FP鼓励用递归或list comprehension,有点洁癖之嫌吧?恩,map的存在可能也是一个原因.
哦,原来这样,为什么不鼓励写loop呢,还有就是python中的异常开销是不是不大?
因为传统上循环总需要个计数器,也就是side effect拉。所以FP鼓励用递归或list comprehension,有点洁癖之嫌吧?
呵呵,python in nutshell 有这么一句
In Python, exceptions are considered appropriate whenever they make a program simpler and more robust, even if that means that exceptions are raised rather frequently
哦,原来这样,为什么不鼓励写loop呢,还有就是python中的异常开销是不是不大?
nnd总算我也懂了,原来把and的计算规则忘了,嘿嘿。
x and y ,if x is false 结果就是x 否则结果是 y.
Reader who are familiar Lisp, Scheme, or functional-programming languages must in particular be aware that Python does not implement the optimization of "tail-call elimination," which is so important in these languages. In Python, any call, recursive or not, has the same cost in terms of both time and memory space, dependent only on the number of arguments: the cost does not change, whether the call is a "tail-call" (meaning that the call is the last operation that the caller executes) or any other, nontail call.
说python中不能实现optimization of "tail-call elimination,"可是我google中搜索了一下发现了这个
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/474088
可是由于不太了解functional-programming 所以the optimization of "tail-call elimination" 也不知道确切的意思,所以也不知道下面的代码写的对不对。
下面的代码是上面的链接里面的那个人写的.
#!/usr/bin/env python2.4 # This program shows off a python decorator( # which implements tail call optimization. It # does this by throwing an exception if it is # it's own grandparent, and catching such # exceptions to recall the stack. import sys class TailRecurseException: def __init__(self, args, kwargs): self.args = args self.kwargs = kwargs def tail_call_optimized(g): """ This function decorates a function with tail call optimization. It does this by throwing an exception if it is it's own grandparent, and catching such exceptions to fake the tail call optimization. This function fails if the decorated function recurses in a non-tail context. """ def func(*args, **kwargs): f = sys._getframe() if f.f_back and f.f_back.f_back \ and f.f_back.f_back.f_code == f.f_code: raise TailRecurseException(args, kwargs) else: while 1: try: return g(*args, **kwargs) except TailRecurseException, e: args = e.args kwargs = e.kwargs func.__doc__ = g.__doc__ return func @tail_call_optimized def factorial(n, acc=1): "calculate a factorial" if n == 0: return acc return factorial(n-1, n*acc) print factorial(10000) # prints a big, big number, # but doesn't hit the recursion limit. @tail_call_optimized def fib(i, current = 0, next = 1): if i == 0: return current else: return fib(i - 1, next, current + next) print fib(10000) # also prints a big number, # but doesn't hit the recursion limit.
评论
17 楼
cookoo
2007-06-12
gigix 写道
cookoo 写道
simohayha 写道
cookoo 写道
不支持也没什么,Ruby也没有,Java spec也不要求。尾递归就是个loop, 直接写loop好了。FP不鼓励写loop那是另外一回事。
哦,原来这样,为什么不鼓励写loop呢,还有就是python中的异常开销是不是不大?
因为传统上循环总需要个计数器,也就是side effect拉。所以FP鼓励用递归或list comprehension,有点洁癖之嫌吧?
至少有一个最新的理由:
函数式的列表操作(map/reduce/filter)是可以拆分的
比如reduce,你可以把一个大列表分成几个小列表,分别对它们做reduce,得到的结果放进同一个列表再做reduce,效果是一样的
map,更是如此
filter,同样
所以你就可以把“分解成小列表的操作”放在几个核上运行
这样就可以充分利用多核的计算能力
大部分情况都如你所说,不过也有例外,比如前后依赖的lazy list:
fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]
另外我觉得这是实现细节,聪明点的编译器也许能辨别能否把loop拆开来并行,比如考虑矩阵相乘操作。
16 楼
gigix
2007-06-11
cookoo 写道
simohayha 写道
cookoo 写道
不支持也没什么,Ruby也没有,Java spec也不要求。尾递归就是个loop, 直接写loop好了。FP不鼓励写loop那是另外一回事。
哦,原来这样,为什么不鼓励写loop呢,还有就是python中的异常开销是不是不大?
因为传统上循环总需要个计数器,也就是side effect拉。所以FP鼓励用递归或list comprehension,有点洁癖之嫌吧?
至少有一个最新的理由:
函数式的列表操作(map/reduce/filter)是可以拆分的
比如reduce,你可以把一个大列表分成几个小列表,分别对它们做reduce,得到的结果放进同一个列表再做reduce,效果是一样的
map,更是如此
filter,同样
所以你就可以把“分解成小列表的操作”放在几个核上运行
这样就可以充分利用多核的计算能力
15 楼
simohayha
2007-06-11
cookoo 写道
simohayha 写道
cookoo 写道
不支持也没什么,Ruby也没有,Java spec也不要求。尾递归就是个loop, 直接写loop好了。FP不鼓励写loop那是另外一回事。
哦,原来这样,为什么不鼓励写loop呢,还有就是python中的异常开销是不是不大?
因为传统上循环总需要个计数器,也就是side effect拉。所以FP鼓励用递归或list comprehension,有点洁癖之嫌吧?
14 楼
cookoo
2007-06-11
simohayha 写道
cookoo 写道
不支持也没什么,Ruby也没有,Java spec也不要求。尾递归就是个loop, 直接写loop好了。FP不鼓励写loop那是另外一回事。
哦,原来这样,为什么不鼓励写loop呢,还有就是python中的异常开销是不是不大?
因为传统上循环总需要个计数器,也就是side effect拉。所以FP鼓励用递归或list comprehension,有点洁癖之嫌吧?
13 楼
simohayha
2007-03-02
Arbow 写道
我说python的异常处理是不是开销不大?Java里面可不敢这样搞
呵呵,python in nutshell 有这么一句
引用
In Python, exceptions are considered appropriate whenever they make a program simpler and more robust, even if that means that exceptions are raised rather frequently
12 楼
simohayha
2007-02-26
cookoo 写道
不支持也没什么,Ruby也没有,Java spec也不要求。尾递归就是个loop, 直接写loop好了。FP不鼓励写loop那是另外一回事。
哦,原来这样,为什么不鼓励写loop呢,还有就是python中的异常开销是不是不大?
11 楼
cookoo
2007-02-15
不支持也没什么,Ruby也没有,Java spec也不要求。尾递归就是个loop, 直接写loop好了。FP不鼓励写loop那是另外一回事。
10 楼
simohayha
2007-02-14
这个我就不懂了。应该是开销不大吧?
9 楼
Arbow
2007-02-14
我说python的异常处理是不是开销不大?Java里面可不敢这样搞
8 楼
simohayha
2007-02-14
if f.f_back and f.f_back.f_back and f.f_back.f_back.f_code == f.f_code
nnd总算我也懂了,原来把and的计算规则忘了,嘿嘿。
x and y ,if x is false 结果就是x 否则结果是 y.
7 楼
Arbow
2007-02-14
sys._getframe:
Frame Object:
总算看懂了,
if f.f_back and f.f_back.f_back and f.f_back.f_back.f_code == f.f_code
当属于自身的递归调用(fib()调用fib())时,上面语句返回true,抛出个 TailRecurseException,然后下面的代码截取异常后直接执行函数。这样就不需要用到堆栈了,也不会溢出。用异常来做控制流啊 多少次递归操作就会抛出多少次异常
引用
_getframe( [depth])
Return a frame object from the call stack. If optional integer depth is given, return the frame object that many calls below the top of the stack. If that is deeper than the call stack, ValueError is raised. The default for depth is zero, returning the frame at the top of the call stack.
This function should be used for internal and specialized purposes only.
Return a frame object from the call stack. If optional integer depth is given, return the frame object that many calls below the top of the stack. If that is deeper than the call stack, ValueError is raised. The default for depth is zero, returning the frame at the top of the call stack.
This function should be used for internal and specialized purposes only.
Frame Object:
引用
Frame objects
Frame objects represent execution frames. They may occur in traceback objects (see below).
Special read-only attributes: f_back is to the previous stack frame (towards the caller), or None if this is the bottom stack frame; f_code is the code object being executed in this frame; f_locals is the dictionary used to look up local variables; f_globals is used for global variables; f_builtins is used for built-in (intrinsic) names; f_restricted is a flag indicating whether the function is executing in restricted execution mode; f_lasti gives the precise instruction (this is an index into the bytecode string of the code object).
Frame objects represent execution frames. They may occur in traceback objects (see below).
Special read-only attributes: f_back is to the previous stack frame (towards the caller), or None if this is the bottom stack frame; f_code is the code object being executed in this frame; f_locals is the dictionary used to look up local variables; f_globals is used for global variables; f_builtins is used for built-in (intrinsic) names; f_restricted is a flag indicating whether the function is executing in restricted execution mode; f_lasti gives the precise instruction (this is an index into the bytecode string of the code object).
总算看懂了,
if f.f_back and f.f_back.f_back and f.f_back.f_back.f_code == f.f_code
当属于自身的递归调用(fib()调用fib())时,上面语句返回true,抛出个 TailRecurseException,然后下面的代码截取异常后直接执行函数。这样就不需要用到堆栈了,也不会溢出。用异常来做控制流啊 多少次递归操作就会抛出多少次异常
6 楼
simohayha
2007-02-13
呵呵,他这边注释说 This function fails if the decorated
function recurses in a non-tail context 。
这段代码我也不懂什么意思
注释也看不太懂
It does this by throwing an exception
if it is it's own grandparent
nnd,好郁闷运行了下10000,显卡驱动直接挂掉,无语了.
function recurses in a non-tail context 。
if f.f_back and f.f_back.f_back \ and f.f_back.f_back.f_code == f.f_code: raise TailRecurseException(args, kwargs)
这段代码我也不懂什么意思
注释也看不太懂
It does this by throwing an exception
if it is it's own grandparent
nnd,好郁闷运行了下10000,显卡驱动直接挂掉,无语了.
5 楼
Arbow
2007-02-13
你给的那段代码:
@tail_call_optimized
标记了这个的function可以被tail_call_optimized这个方法proxy,查看tail_call_optimized(g),它应该是先判断此方法是否为尾递归类型?我也不太清楚
如果是,则执行这个函数,当抛出TailRecurseException时就截获它,然后再次继续执行下去,避免堆栈不够的问题。
尾递归方式的函数,执行起来还是跟迭代差不多快的,主要是python不执行这种优化,有stack容量限制,这个proxy就解决它了,比较精妙,收藏一下
@tail_call_optimized
标记了这个的function可以被tail_call_optimized这个方法proxy,查看tail_call_optimized(g),它应该是先判断此方法是否为尾递归类型?我也不太清楚
if f.f_back and f.f_back.f_back \ and f.f_back.f_back.f_code == f.f_code: raise TailRecurseException(args, kwargs)
如果是,则执行这个函数,当抛出TailRecurseException时就截获它,然后再次继续执行下去,避免堆栈不够的问题。
else: while 1: try: return g(*args, **kwargs) except TailRecurseException, e: args = e.args kwargs = e.kwargs
尾递归方式的函数,执行起来还是跟迭代差不多快的,主要是python不执行这种优化,有stack容量限制,这个proxy就解决它了,比较精妙,收藏一下
4 楼
simohayha
2007-02-13
python 中的递归是有 限制的,默认情况下over a depth of 1,000就会抛出异常,可是你还能通过sys模块的setrecursionlimit来设置递归的限制,不过这个设置也是有限制的,它依赖于你的操作系统和c的库,文档里面好像说 大概不会超过 几千层.
呵呵那段代码现在基本能看懂了.
ps:不知道为什么python不把 尾递归优化 加进去,嘿嘿,希望下个版本能加进去.
呵呵那段代码现在基本能看懂了.
ps:不知道为什么python不把 尾递归优化 加进去,嘿嘿,希望下个版本能加进去.
3 楼
Arbow
2007-02-13
优化是编译器/解析器来做的,但是这种风格的代码需要自己来写。
貌似python没有做这优化处理,计算10000就出问题了:
就会出错了
栈溢出
http://www.iteye.com/t/17585.html
应该是没有优化了
貌似python没有做这优化处理,计算10000就出问题了:
print "Fibonacci(10000)=", fib(10000) print "Total time:", (time.time()*1000-t*1000)
就会出错了
引用
...
File "Fib.py", line 9, in tailRecursionFib
return tailRecursionFib(n-1, f1+f2, f1)
File "Fib.py", line 9, in tailRecursionFib
return tailRecursionFib(n-1, f1+f2, f1)
RuntimeError: maximum recursion depth exceeded
File "Fib.py", line 9, in tailRecursionFib
return tailRecursionFib(n-1, f1+f2, f1)
File "Fib.py", line 9, in tailRecursionFib
return tailRecursionFib(n-1, f1+f2, f1)
RuntimeError: maximum recursion depth exceeded
栈溢出
http://www.iteye.com/t/17585.html
应该是没有优化了
2 楼
simohayha
2007-02-13
那么python 中可是实现这种优化吗?
那么 象 FP语言 中的尾递归优化 是自动的?还是说要你自己实现?
ps: 论坛现在的搜索好不稳定,经常就什么都搜索不出来了.
那么 象 FP语言 中的尾递归优化 是自动的?还是说要你自己实现?
ps: 论坛现在的搜索好不稳定,经常就什么都搜索不出来了.
1 楼
Arbow
2007-02-13
是指“尾递归优化”吧,比如下面的程序
return tailRecursionFib(n-1, f1+f2, f1) 这行递归调用,可以直接优化为跳转指令而不是函数调用(需要保存堆栈),这样速度会快很多,接近于迭代。以前T1讨论过的,很多FP语言都支持这种优化。
e.找到了,见 http://www.iteye.com/post/32289 的最下面
def fib(n): if(n==0): return 0; return tailRecursionFib(n,1,0) def tailRecursionFib(n, f1, f2): if(n==1): return f1 return tailRecursionFib(n-1, f1+f2, f1) import time t = time.time() print "Fibonacci(700)=", fib(700) print "Total time:", (time.time()*1000-t*1000)
return tailRecursionFib(n-1, f1+f2, f1) 这行递归调用,可以直接优化为跳转指令而不是函数调用(需要保存堆栈),这样速度会快很多,接近于迭代。以前T1讨论过的,很多FP语言都支持这种优化。
e.找到了,见 http://www.iteye.com/post/32289 的最下面
发表评论
-
Python3K Alpha1放出
2007-09-01 00:47 2186详细情况请看这里: http://python.org/do ... -
py3000的一些信息
2007-07-31 20:09 2691原文看这里 http://www.artima.com/web ... -
Python 3000 Status Update
2007-06-19 19:23 2199http://www.artima.com/weblogs/v ... -
操作符is的1个诡异问题
2007-06-13 09:44 2914请看这段程序 a = 0 b = 0 while a ... -
projecteulerProblem(1-10)
2007-04-14 21:22 3624地址在下面,都是些有趣的数学题,有兴趣的可以去玩玩. http ... -
python之父要来北京了。
2007-04-13 10:01 3544May 31 is Google Developer Day ... -
今天Python2.5.1release了
2007-04-12 10:06 2402http://www.python.org/download/ ... -
Peter Norvig用python写的拼写纠错
2007-04-11 10:19 3580文章在这里: http://www.norvig.com/sp ... -
今天发现了一个非常有意思的regex
2007-03-20 10:24 2697判断一个数是否为质数的方法: import re de ... -
这里有个讲Fp的文章,讲的很是有趣.
2007-03-13 14:31 3727http://chn.blogbeta.com/232.htm ... -
python中的Error-checking策略
2007-03-02 21:12 4331参考 python in nutshe ... -
关于类中slots属性的用法的疑问
2007-02-28 10:07 4661__slots__保存着实例变量的列表,并且在实例中保留空间以 ... -
Jython Beta and 2.2 发布了
2007-02-09 21:26 4065本以为已经挂了,今天无意中去逛了一下,竟然更新了,而且看了它的 ... -
python 中古怪的input()错误(已解决)
2006-11-23 15:15 7694在windows下 width = input('Pleas ...
相关推荐
在Python中实现这一功能,主要有以下几个知识点需要掌握: 1. 文件监控机制:在Unix/Linux系统中,可以利用inotify机制来监控文件系统的事件,如文件被打开、修改、删除等。inotify机制通过内核模块,提供了一种...
通过阅读这些源代码,开发者可以了解File-Tail如何实现文件监控,包括文件句柄管理、信号处理、内存管理等方面的知识。 在实际应用中,File-Tail-0.99.3可以广泛应用于系统监控、网络日志分析等领域。例如,在Web...
实现window系统下 类似 Linux 命令行 tail -f 功能.使用C#语言开发,占用资源小。如有问题可留言
在传统的DOS操作系统环境下,与Unix/Linux系统中的`tail`命令类似的功能,可以通过特定的工具实现。`tail`命令在Unix/Linux中常用于查看文件的末尾内容,特别是跟踪文件的实时更新,这对于日志监控或者调试过程非常...
资源分类:Python库 所属语言:Python 资源全名:tail-tools-0.19.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
然而,通过在给定的压缩包中提取 `tail.exe` 文件并将其放置在 `C:\Windows\System32` 目录下,我们可以为 Windows 创建类似的功能。 `tail` 命令的基本用途是显示文件的末尾几行。默认情况下,它会显示文件的最后...
tailf与tail -f类似:当文件不增长时并不访问文件 tail -f:只跟踪文件内容 tail -F:文件内容与文件名都跟踪 这篇文章最初是因为reboot的群里,有人去面试,笔试题有这个题,不知道怎么做,什么思路,就发群里大家...
**File-Tail-Scribe** 是一个专用于收集和处理日志文件的工具模块,它在IT行业中被广泛用于监控和分析系统、应用或服务产生的日志数据。在现代的运维和开发环境中,日志文件是排查问题、追踪系统行为、进行性能优化...
Java作为一种广泛使用的编程语言,也可以实现类似`tail`的功能。本篇文章将深入探讨如何使用Java来实现`tail`命令的核心功能,即查看指定文件的最后N行。 首先,我们需要理解`tail`命令的基本工作原理。`tail`通常...
在Linux系统中,`tail`命令是一个非常常用的工具,它用于查看文件的末尾部分,通常用于监控日志文件的变化。然而,对于实时监控动态更新的日志文件,`tail -f`选项则更为实用。本篇文章将深入探讨`tail -f`的功能...
在Python中,虽然标准解释器并未默认开启尾递归优化,但一些编译器如Jython和PyPy则支持这一特性。 tail_recursion库的目的是帮助Python程序员实现尾递归优化,即使在标准的CPython环境下也能尽可能地减少递归带来...
### Python编程实现tail-n查看日志文件的方法 在日常的软件开发与运维工作中,经常会遇到需要查看日志文件的需求,尤其是对于大型应用的日志管理。传统的`tail -n`命令可以很方便地帮助我们查看文件的最后几行内容...
babel-plugin-tailcall优化 JavaScript的尾调用优化!安装npm install babel-plugin-tailcall-optimization --save-dev 并添加到您的.babelrc : "plugins" : [ "tailcall-optimization" ] 如果您使用babel @ 6,请...
首先,`tail.exe`是主要的执行程序,它是Windows下的`tail`工具,用户只需将这个文件解压到系统盘下,然后在命令行界面中运行,就可以实时查看指定日志文件的尾部内容。这极大地提升了Windows用户在处理日志文件时的...
在启动WebLogic服务器或其他类似服务时,使用`nohup`和`tail -f`的组合可以实现以下流程: 1. 使用`nohup`启动WebLogic服务器: ```bash nohup ./startWeblogic & ``` 这样,即使你关闭终端,WebLogic服务器也会...
首先,你需要将`tail.exe`文件复制到`C:\Windows\System32`目录下,因为这是Windows系统路径的一部分,这样可以在任意命令提示符窗口中直接调用`tail`命令。然后,通过命令行(CMD或PowerShell)输入`tail -f xxx....
k8stail使您可以实时监视指定名称空间中的所有pod的日志流或标签,如tail -f 。 目录 选项 发展 作者 执照 要求 Kubernetes 1.3或以上 安装 使用自制软件(仅适用于OS X) 公式可从dtan4 / homebrew-dtan4获得...
tail for Windows 是 Windows 下的 tail DOS 命令(类似 UNIX/Linux 下的相同命令)。可用来显示文件尾部内容以及跟踪/监控文件内容变化。你也可以借助重定向符号(> 或 >>)从一个文件的指定行号开始截取内容生成另...