Python 2 vs Python 3 - Размер целого числа [дубликат]

Вы можете попробовать использовать библиотеку TinyPNG PHP. Используя эту библиотеку, ваш образ автоматически оптимизируется во время процесса изменения размера. Все, что вам нужно, чтобы установить библиотеку и получить ключ API из https://tinypng.com/developers . Чтобы установить библиотеку, выполните следующую команду:

composer require tinify/tinify

После этого ваш код выглядит следующим образом.

require_once("vendor/autoload.php");

\Tinify\setKey("YOUR_API_KEY");

$source = \Tinify\fromFile("large.jpg"); //image to be resize
$resized = $source->resize(array(
    "method" => "fit",
    "width" => 150,
    "height" => 100
));
$resized->toFile("thumbnail.jpg"); //resized image

У меня есть блог в той же теме http://artisansweb.net/resize-image-php-using-tinypng

20
задан Hailiang Zhang 28 April 2012 в 18:31
поделиться

1 ответ

Короткий ответ

Вы получаете размер класса , а не экземпляр класса. Вызовите int, чтобы получить размер экземпляра:

>>> sys.getsizeof(int())
24

Если этот размер все еще кажется немного большим, помните, что Python int сильно отличается от int in (for пример) c. В Python int является полнофункциональным объектом. Это означает, что дополнительные накладные расходы.

Каждый объект Python содержит по крайней мере refcount и ссылку на тип объекта в дополнение к другому хранилищу; на 64-битной машине, которая занимает 16 байтов! Внутренние элементы int (как определено стандартной реализацией CPython) также со временем изменились, поэтому количество дополнительного хранилища зависит от вашей версии.

Некоторые подробности об объектах int в Python 2 и 3

Вот ситуация в Python 2. (Некоторые из них адаптированы из сообщения в блоге Laurent Luce ). Целочисленные объекты представляются в виде блоков памяти со следующей структурой:

typedef struct {
    PyObject_HEAD
    long ob_ival;
} PyIntObject;

PyObject_HEAD - это макрос, определяющий хранилище для refcount и типа объекта. Это подробно описано в документации , и код можно увидеть в ответе .

Память выделяется большими блоками, так что есть а не узкое место для каждого нового целого. Структура блока выглядит так:

struct _intblock {
    struct _intblock *next;
    PyIntObject objects[N_INTOBJECTS];
};
typedef struct _intblock PyIntBlock;

Сначала все пустые. Затем каждый раз, когда создается новое целое число, Python использует память, на которую указывает next, и увеличивает next, чтобы указать на следующий свободный целочисленный объект в блоке.

Я не совсем уверен как это изменяется, если вы превысите емкость хранилища обычного числа, но как только вы это сделаете, размер int станет больше. На моей машине в Python 2:

>>> sys.getsizeof(0)
24
>>> sys.getsizeof(1)
24
>>> sys.getsizeof(2 ** 62)
24
>>> sys.getsizeof(2 ** 63)
36

В Python 3 я думаю, что общая картина такая же, но размер целых чисел увеличивается более по частям:

>>> sys.getsizeof(0)
24
>>> sys.getsizeof(1)
28
>>> sys.getsizeof(2 ** 30 - 1)
28
>>> sys.getsizeof(2 ** 30)
32
>>> sys.getsizeof(2 ** 60 - 1)
32
>>> sys.getsizeof(2 ** 60)
36

Эти результаты, конечно, зависят от оборудования! YMMV.

Изменчивость целочисленного размера в Python 3 - это намек на то, что они могут вести себя как типы переменной длины (например, списки). И действительно, это оказывается правдой. Вот определение C struct для объектов int в Python 3:

struct _longobject {
    PyObject_VAR_HEAD
    digit ob_digit[1];
};

Комментарии , которые сопровождают это определение, суммируют Python 3 - целые числа. Нуль представлен не хранимым значением, а объектом с нулевым размером (поэтому sys.getsizeof(0) является 24 байтами, а sys.getsizeof(1) - 28). Отрицательные числа представлены объектами с атрибутом отрицательного размера! Настолько странно.

44
ответ дан senderle 25 August 2018 в 20:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: