首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么python实现使用的内存比C多9倍?

为什么python实现使用的内存比C多9倍?
EN

Stack Overflow用户
提问于 2019-03-27 06:37:02
回答 1查看 376关注 0票数 7

我写了一个程序,用python和C编写了一个从2到用户给定数字的素数列表,我运行了这两个程序,寻找相同数字的素数,并在活动监视器中查看它们各自的进程。我发现python实现使用的内存恰好是C实现的9倍。为什么python需要如此多的内存,为什么特定的倍数要存储相同的整数数组?下面是程序的两个实现:

Python版本:

代码语言:javascript
复制
import math
import sys

top = int(input('Please enter the highest number you would like to have checked: '))
num = 3
prime_list = [2]
while num <= top:
    n = 0
    prime = True
    while int(prime_list[n]) <= math.sqrt(num):
        if num % prime_list[n] == 0:
            prime = False
            n = 0
            break
        n = n + 1
    if prime == True:
        prime_list.append(num)
        prime = False
    num = num + 1
print("I found ", len(prime_list), " primes")
print("The largest prime I found was ", prime_list[-1])

C版本:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
    int N;
    int arraySize = 1;
    int *primes = malloc(100*sizeof(int));
    int isPrime = 1;
    primes[0] = 2;
    int timesRealloc = 0;
    int availableSlots = 100;

    printf("Please enter the largest number you want checked: \n");
    scanf("%d", &N);

    int j = 0;
    int i;
    for (i = 3; i <= N; i+=2){
        j = 0;
        isPrime = 1;
        while (primes[j] <= sqrt(i)) {
            if (i%primes[j] == 0) {
                isPrime = 0;
                break;
            }
            j++;
        }
        if (isPrime == 1){
            primes[arraySize] = i;
            arraySize++;
        }
        if (availableSlots == arraySize){
            timesRealloc++;
            availableSlots += 100;
            primes = realloc(primes, availableSlots*sizeof(int));
        }
    }

    printf("I found %d primes\n", arraySize);
    printf("Memory was reallocated %d times\n", timesRealloc);
    printf("The largest prime I found was %d\n", primes[(arraySize-1)]);


    return 0;
}
EN

回答 1

Stack Overflow用户

发布于 2019-03-27 06:45:25

代码语言:javascript
复制
>>> import sys
>>> sys.getsizeof(123456)
28

这是C int的7倍大小。在Python3中,整数是struct _longobject的实例,也称为PyLong

代码语言:javascript
复制
struct _longobject {
    PyVarObject ob_base;
    digit ob_digit[1];
};

PyVarObject在哪里

代码语言:javascript
复制
typedef struct {
    PyObject ob_base;
    Py_ssize_t ob_size;
} PyVarObject;

PyObject

代码语言:javascript
复制
typedef struct _object {
    Py_ssize_t ob_refcnt;
    struct _typeobject *ob_type;
} PyObject;

由此,我们得到了64位Python版本中该对象123456的以下内存使用量:

(Py_ssize_t)

  • 8

  • 8字节用于引用计数器Py_ssize_t)

  • 4字节用于指向类型对象字节的指针(类型为
  • ,用于计算对象的可变长度部分中的字节数;类型为Py_ssize_t)
  • 4 &PyLong_Type,用于整数中每30位数字。

由于123456适合前30位,因此总和为28,即7 * sizeof (int)

此外,Python中的每个元素都是指向实际对象的PyObject *;在64位Python构建中,每个指针都是64位的;这意味着每个列表元素引用本身消耗的内存是C int的两倍。

将7和2相加,就可以得到9

对于存储效率更高的代码,您可以使用arrays;对于类型代码'i',内存消耗应该与C版本非常接近。arrayappend方法,多亏了这个方法,数组的增长应该比使用realloc的C/更容易。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55367167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档