Python论坛  - 讨论区

标题:[python-chinese] 为什么这个程序这么占用内存呢

2005年08月03日 星期三 18:51

saddle saddle at gmail.com
Wed Aug 3 18:51:49 HKT 2005

最近新出来一本书, begining python,里面一个简单的演示thread的程序。
发现给它一个比较大的数字时候,就会占用很多虚拟内存, 大约500M, 我这儿只
设置了这么多虚拟内存...
import math
from threading import Thread
import time
class SquareRootCalculator:
    """This class spawns a separate thread to calculate a bunch of square
    roots, and checks in it once a second until it finishes."""
    def __init__(self, target):
        """Turn on the calculator thread and, while waiting for it to
        finish, periodically monitor its progress."""
        self.results = []
        counter = self.CalculatorThread(self, target)
        print "Turning on the calculator thread..."
        counter.start()
        while len(self.results) < target:
            print "%d square roots calculated so far." % len(self.results)
            time.sleep(1)
        print "Calculated %s square root(s); the last one is sqrt(%d)=%f" % \
            (target, len(self.results), self.results[-1])
    class CalculatorThread(Thread):
        """A separate thread which actually does the calculations."""
        def __init__(self, controller, target):
            """Set up this thread, including making it a daemon thread
            so that the script can end without waiting for this thread to
            finish."""
            Thread.__init__(self)
            self.controller = controller
            self.target = target
            self.setDaemon(True)
        def run(self):
            """Calculate square roots for all numbers between 1 and the target,
            inclusive."""
            for i in range(1, self.target+1):
                self.controller.results.append(math.sqrt(i))

if __name__ == '__main__':
    import sys
    limit = None
    if len(sys.argv) > 1:
        limit = sys.argv[1]
        try:
            limit = int(limit)
        except ValueError:
            print "Usage: %s [number of square roots to calculate]" \
                % sys.argv[0]    
    SquareRootCalculator(limit)


[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月03日 星期三 19:02

Qiangning Hong hongqn at gmail.com
Wed Aug 3 19:02:35 HKT 2005

On 8/3/05, saddle <saddle at gmail.com> wrote:
> 最近新出来一本书, begining python,里面一个简单的演示thread的程序。
> 发现给它一个比较大的数字时候,就会占用很多虚拟内存, 大约500M, 我这儿只
> 设置了这么多虚拟内存...
[snip the code]

你给了多大的一个数?程序里面用一个list保存所有运算结果,算得数多了,内存占用自然就上去了。

-- 
Qiangning Hong

I'm usually annoyed by IDEs because, for instance, they don't use VIM
as an editor. Since I'm hooked to that, all IDEs I've used so far have
failed to impress me.
   -- Sybren Stuvel @ c.l.python

Get Firefox! <http://www.spreadfirefox.com/?q=affiliates&id=67907&t=1>

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月03日 星期三 21:10

saddle saddle at gmail.com
Wed Aug 3 21:10:33 HKT 2005

我自己修改了那个,没有用list, 直接返回结果,也是用很大的内存,而且有时
候算不出来了.
设定的数字比较大的整数,不过我感觉没有哪个list, 应该就不用占用多少内存
了。
On Wed, 3 Aug 2005 19:02:35 +0800
Qiangning Hong <hongqn at gmail.com> 撰写于:

hongqn> On 8/3/05, saddle <saddle at gmail.com> wrote:
hongqn> > 最近新出来一本书, begining python,里面一个简单的演示thread的程序。
hongqn> > 发现给它一个比较大的数字时候,就会占用很多虚拟内存, 大约500M, 我这儿只
hongqn> > 设置了这么多虚拟内存...
hongqn> [snip the code]
hongqn> 
hongqn> 你给了多大的一个数?程序里面用一个list保存所有运算结果,算得数多了,内存占用自然就上去了。
hongqn> 
hongqn> -- 
hongqn> Qiangning Hong
hongqn> 
hongqn> I'm usually annoyed by IDEs because, for instance, they don't use VIM
hongqn> as an editor. Since I'm hooked to that, all IDEs I've used so far have
hongqn> failed to impress me.
hongqn>    -- Sybren Stuvel @ c.l.python
hongqn> 
hongqn> Get Firefox! <http://www.spreadfirefox.com/?q=affiliates&id=67907&t=1>



[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月03日 星期三 22:44

Jason Liu telecomliu at gmail.com
Wed Aug 3 22:44:26 HKT 2005

在 05-8-3,saddle<saddle at gmail.com> 写道:
> 我自己修改了那个,没有用list, 直接返回结果,也是用很大的内存,而且有时
> 候算不出来了.
不用list应该不会占多少内存

> 设定的数字比较大的整数,不过我感觉没有哪个list, 应该就不用占用多少内存
> 了。
比较大是多大?十的10次方数量级?

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月03日 星期三 23:09

Henry learning.python at gmail.com
Wed Aug 3 23:09:41 HKT 2005

Jason Liu wrote:
> 在 05-8-3,saddle<saddle at gmail.com> 写道:
> 
>>我自己修改了那个,没有用list, 直接返回结果,也是用很大的内存,而且有时
>>候算不出来了.
> 
> 不用list应该不会占多少内存
> 
> 
>>设定的数字比较大的整数,不过我感觉没有哪个list, 应该就不用占用多少内存
>>了。
> 
> 比较大是多大?十的10次方数量级?
> 
为什么这个程序我无法run?active python 2.4


[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月04日 星期四 00:43

saddle saddle at gmail.com
Thu Aug 4 00:43:08 HKT 2005

1111111 这个数字就要用179M的内存和177M的虚拟内存
用的是下面我改写了几句的代码,没有list了。
On Wed, 3 Aug 2005 22:44:26 +0800
Jason Liu <telecomliu at gmail.com> 撰写于:

telecomliu> 在 05-8-3,saddle<saddle at gmail.com> 写道:
telecomliu> > 我自己修改了那个,没有用list, 直接返回结果,也是用很大的内存,而且有时
telecomliu> > 候算不出来了.
telecomliu> 不用list应该不会占多少内存
telecomliu> 
telecomliu> > 设定的数字比较大的整数,不过我感觉没有哪个list, 应该就不用占用多少内存
telecomliu> > 了。
telecomliu> 比较大是多大?十的10次方数量级?



import math
from threading import Thread
import time
class SquareRootCalculator:
    """This class spawns a separate thread to calculate a bunch of square
    roots, and checks in it once a second until it finishes."""
    def __init__(self, target):
        """Turn on the calculator thread and, while waiting for it to
        finish, periodically monitor its progress."""
        #self.results = []
        self.r2 = 0
        self.results = 0
        counter = self.CalculatorThread(self, target)
        print "Turning on the calculator thread..."
        counter.start()
        #while len(self.results) < target:
        while self.r2 < target:
            #print "%d square roots calculated so far." % len(self.results)
            print "%d square roots calculated so far." % (self.r2)
            time.sleep(1)
        print "Calculated %s square root(s); the last one is sqrt(%d)=%f" % \
            (target, self.r2, self.results)
            #(target, len(self.results), self.results[-1])
    class CalculatorThread(Thread):
        """A separate thread which actually does the calculations."""
        def __init__(self, controller, target):
            """Set up this thread, including making it a daemon thread
            so that the script can end without waiting for this thread to
            finish."""
            Thread.__init__(self)
            self.controller = controller
            self.target = target
            self.setDaemon(True)
        def run(self):
            """Calculate square roots for all numbers between 1 and the target,
            inclusive."""
            for i in range(1, self.target+1):
                #self.controller.results.append(math.sqrt(i))
                self.controller.results=math.sqrt(i)
                self.controller.r2 = i

if __name__ == '__main__':
    import sys
    limit = None
    if len(sys.argv) > 1:
        limit = sys.argv[1]
        try:
            limit = int(limit)
        except ValueError:
            print "Usage: %s [number of square roots to calculate]" \
                % sys.argv[0]    
    SquareRootCalculator(limit)

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月04日 星期四 10:19

saddle saddle at gmail.com
Thu Aug 4 10:19:44 HKT 2005

我这儿修改前后的都可以运行,也是 activepython 2.41
可能是复制粘贴代码时候格式有问题吧, 
不知道这个mail list可不可以贴附件的
On Wed, 03 Aug 2005 23:09:41 +0800
Henry <learning.python at gmail.com> 撰写于:

learning.python> Jason Liu wrote:
learning.python> > 在 05-8-3,saddle<saddle at gmail.com> 写道:
learning.python> > 
learning.python> >>我自己修改了那个,没有用list, 直接返回结果,也是用很大的内存,而且有时
learning.python> >>候算不出来了.
learning.python> > 
learning.python> > 不用list应该不会占多少内存
learning.python> > 
learning.python> > 
learning.python> >>设定的数字比较大的整数,不过我感觉没有哪个list, 应该就不用占用多少内存
learning.python> >>了。
learning.python> > 
learning.python> > 比较大是多大?十的10次方数量级?
learning.python> > 
learning.python> 为什么这个程序我无法run?active python 2.4
learning.python> 
learning.python> _______________________________________________
learning.python> python-chinese list
learning.python> python-chinese at lists.python.cn
learning.python> http://python.cn/mailman/listinfo/python-chinese



[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月04日 星期四 10:58

wwwbbk wwwbbk at gmail.com
Thu Aug 4 10:58:15 HKT 2005

问题出在“range(1, self.target+1)”,用while循环代替,就可以了。下面是我改写
后的程序:
# begin
import math
from threading import Thread
import time
class SquareRootCalculator:
    """This class spawns a separate thread to calculate a bunch of square
    roots, and checks in it once a second until it finishes."""
    def __init__(self, target):
        """Turn on the calculator thread and, while waiting for it to
        finish, periodically monitor its progress."""
        #self.results = []
        self.r2 = 0
        self.results = 0
        counter = self.CalculatorThread(self, target)
        print "Turning on the calculator thread..."
        counter.start()
        #while len(self.results) < target:
        while self.r2 < target:
            #print "%d square roots calculated so far." % len(self.results)
            print "%d square roots calculated so far." % (self.r2)
            time.sleep(1)
        print "Calculated %s square root(s); the last one is sqrt(%d)=%f" %
\
            (target, self.r2, self.results)
            #(target, len(self.results), self.results[-1])
    class CalculatorThread(Thread):
        """A separate thread which actually does the calculations."""
        def __init__(self, controller, target):
            """Set up this thread, including making it a daemon thread
            so that the script can end without waiting for this thread to
            finish."""
            Thread.__init__(self)
            self.controller = controller
            self.target = target
            self.setDaemon(True)
        def run(self):
            """Calculate square roots for all numbers between 1 and the
target,
            inclusive."""
            i = 1
            while i < self.target+1:
            #for i in range(1, self.target+1):
                #self.controller.results.append(math.sqrt(i))
                self.controller.results=math.sqrt(i)
                self.controller.r2 = i
                i = i+1

if __name__ == '__main__':
    import sys
    limit = None
    if len(sys.argv) > 1:
        limit = sys.argv[1]
        try:
            limit = int(limit)
        except ValueError:
            print "Usage: %s [number of square roots to calculate]" \
                % sys.argv[0]
    SquareRootCalculator(limit)
# end

-----邮件原件-----
发件人: python-chinese-bounces at lists.python.cn
[mailto:python-chinese-bounces at lists.python.cn] 代表 saddle
发送时间: 2005年8月4日 0:43
收件人: python-chinese at lists.python.cn
主题: Re: [python-chinese]为什么这个程序这么占用内存呢

1111111 这个数字就要用179M的内存和177M的虚拟内存
用的是下面我改写了几句的代码,没有list了。
On Wed, 3 Aug 2005 22:44:26 +0800
Jason Liu <telecomliu at gmail.com> 撰写于:

telecomliu> 在 05-8-3,saddle<saddle at gmail.com> 写道:
telecomliu> > 我自己修改了那个,没有用list, 直接返回结果,也是用很大的内
存,而且有时
telecomliu> > 候算不出来了.
telecomliu> 不用list应该不会占多少内存
telecomliu> 
telecomliu> > 设定的数字比较大的整数,不过我感觉没有哪个list, 应该就不用占
用多少内存
telecomliu> > 了。
telecomliu> 比较大是多大?十的10次方数量级?



import math
from threading import Thread
import time
class SquareRootCalculator:
    """This class spawns a separate thread to calculate a bunch of square
    roots, and checks in it once a second until it finishes."""
    def __init__(self, target):
        """Turn on the calculator thread and, while waiting for it to
        finish, periodically monitor its progress."""
        #self.results = []
        self.r2 = 0
        self.results = 0
        counter = self.CalculatorThread(self, target)
        print "Turning on the calculator thread..."
        counter.start()
        #while len(self.results) < target:
        while self.r2 < target:
            #print "%d square roots calculated so far." % len(self.results)
            print "%d square roots calculated so far." % (self.r2)
            time.sleep(1)
        print "Calculated %s square root(s); the last one is sqrt(%d)=%f" %
\
            (target, self.r2, self.results)
            #(target, len(self.results), self.results[-1])
    class CalculatorThread(Thread):
        """A separate thread which actually does the calculations."""
        def __init__(self, controller, target):
            """Set up this thread, including making it a daemon thread
            so that the script can end without waiting for this thread to
            finish."""
            Thread.__init__(self)
            self.controller = controller
            self.target = target
            self.setDaemon(True)
        def run(self):
            """Calculate square roots for all numbers between 1 and the
target,
            inclusive."""
            for i in range(1, self.target+1):
                #self.controller.results.append(math.sqrt(i))
                self.controller.results=math.sqrt(i)
                self.controller.r2 = i

if __name__ == '__main__':
    import sys
    limit = None
    if len(sys.argv) > 1:
        limit = sys.argv[1]
        try:
            limit = int(limit)
        except ValueError:
            print "Usage: %s [number of square roots to calculate]" \
                % sys.argv[0]    
    SquareRootCalculator(limit)
_______________________________________________
python-chinese list
python-chinese at lists.python.cn
http://python.cn/mailman/listinfo/python-chinese


[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月04日 星期四 11:42

黑沙 fred.li.1979.m.bj.prc at gmail.com
Thu Aug 4 11:42:29 HKT 2005

我执行你一开始给的代码就有下列问题:
Turning on the calculator thread...
Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\python24\lib\threading.py", line 442, in __bootstrap
    self.run()
  File "thread.py", line 32, in run
    for i in range(1, self.target+1):
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

Traceback (most recent call last):
  File "thread.py", line 45, in ?
    SquareRootCalculator(limit)
  File "thread.py", line 17, in __init__
    print "Calculated %s square root(s); the last one is sqrt(%d)=%f" % \
IndexError: list index out of range

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月04日 星期四 12:38

Jason Liu telecomliu at gmail.com
Thu Aug 4 12:38:43 HKT 2005

在 05-8-4,saddle<saddle at gmail.com> 写道:
> 1111111 这个数字就要用179M的内存和177M的虚拟内存

在我的机器上8个1差不多能用到这个数,看你的代码是正常的

>    class CalculatorThread(Thread):
>        """A separate thread which actually does the calculations."""
>        def __init__(self, controller, target):
>        def run(self):
>            """Calculate square roots for all numbers between 1 and the target,
>            inclusive."""
>            for i in range(1, self.target+1):

应该就是这个range()占用的内存

>                #self.controller.results.append(math.sqrt(i))
>                self.controller.results=math.sqrt(i)
>                self.controller.r2 = i

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月04日 星期四 14:10

saddle saddle at gmail.com
Thu Aug 4 14:10:44 HKT 2005

哦,这个程序好像书里面自己写的不太严格, 最后一行的
SquareRootCalculator(limit)应该向右四个字节,这样就不出错了, 不过没有参
数是无意义的。
假设这个文件你保存为sqrt.py 你可以试试命令行下面, sqrt 999 这时计算999
的平方根。
On Thu, 4 Aug 2005 11:42:29 +0800
黑沙 <fred.li.1979.m.bj.prc at gmail.com> 撰写于:

fred.li.1979.m.bj.prc> 我执行你一开始给的代码就有下列问题:
fred.li.1979.m.bj.prc> Turning on the calculator thread...
fred.li.1979.m.bj.prc> Exception in thread Thread-1:
fred.li.1979.m.bj.prc> Traceback (most recent call last):
fred.li.1979.m.bj.prc>   File "C:\python24\lib\threading.py", line 442, in __bootstrap
fred.li.1979.m.bj.prc>     self.run()
fred.li.1979.m.bj.prc>   File "thread.py", line 32, in run
fred.li.1979.m.bj.prc>     for i in range(1, self.target+1):
fred.li.1979.m.bj.prc> TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
fred.li.1979.m.bj.prc> 
fred.li.1979.m.bj.prc> Traceback (most recent call last):
fred.li.1979.m.bj.prc>   File "thread.py", line 45, in ?
fred.li.1979.m.bj.prc>     SquareRootCalculator(limit)
fred.li.1979.m.bj.prc>   File "thread.py", line 17, in __init__
fred.li.1979.m.bj.prc>     print "Calculated %s square root(s); the last one is sqrt(%d)=%f" % \
fred.li.1979.m.bj.prc> IndexError: list index out of range



[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月04日 星期四 14:28

saddle saddle at gmail.com
Thu Aug 4 14:28:20 HKT 2005

多谢多谢,
恩,我这儿也是8个1时候大约这么多内存占用, 
总结一下, 
占用内存的主要是两个地方
第一个, self.controller.results.append(math.sqrt(i)), 不停的往results
这个list里面添加数据进去,
第二个, for i in range(1, self.target+1)这一句要生成一个比较大的list,
也占用了相当多内存
计算8个1的平方根时候, 如果两个地方都不用list, 大约占用3.6M内存和1.6M虚
拟内存, 如果第二个range使用, 会稳定占用170M左右的内存和170左右的虚拟内
存,如果第二个不用range, 而第一个不停地往reuslts里面添加数据, 占用内存
越来越多,这看到的是快计算结束时候,大约200M左右的内存和200M左右的虚拟内
存, 

另外, 一开始没有想到range占用了这么多内存,range可以用xrange来代替就不会
耗费这么多内存了,我估计对比较小的list, range可能会速度上面更快一些,
On Thu, 4 Aug 2005 12:38:43 +0800
Jason Liu <telecomliu at gmail.com> 撰写于:

telecomliu> 在 05-8-4,saddle<saddle at gmail.com> 写道:
telecomliu> > 1111111 这个数字就要用179M的内存和177M的虚拟内存
telecomliu> 
telecomliu> 在我的机器上8个1差不多能用到这个数,看你的代码是正常的
telecomliu> 
telecomliu> >    class CalculatorThread(Thread):
telecomliu> >        """A separate thread which actually does the calculations."""
telecomliu> >        def __init__(self, controller, target):
telecomliu> >        def run(self):
telecomliu> >            """Calculate square roots for all numbers between 1 and the target,
telecomliu> >            inclusive."""
telecomliu> >            for i in range(1, self.target+1):
telecomliu> 
telecomliu> 应该就是这个range()占用的内存
telecomliu> 
telecomliu> >                #self.controller.results.append(math.sqrt(i))
telecomliu> >                self.controller.results=math.sqrt(i)
telecomliu> >                self.controller.r2 = i



[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月04日 星期四 17:00

agile java agile.java at gmail.com
Thu Aug 4 17:00:54 HKT 2005

range确实会占用很大的内存,以前发现过这个问题,当时还不知道xrange,没办法,当时只好自己计数了:(

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年08月05日 星期五 00:00

saddle saddle at gmail.com
Fri Aug 5 00:00:46 HKT 2005

例如从字符串 str1 = 'abcxxxasdf'里面匹配多个模式
p1 = 'aaa', p2='abc', p3= 'xxx'。
用正则表达式应该可以只读取一次str1就可以了,
不过,不知道有更好的优化方法,例如p1,p2都是a开头的,可以例用上用来加速匹
配么
哪位作过类似的东西, 能谈谈看法么。

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2025

    京ICP备05028076号