<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Idi Suda</title><author><name>Idi Suda</name></author><id>https://teletype.in/atom/bvrch</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/bvrch?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@bvrch?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=bvrch"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/bvrch?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-05-13T20:37:56.629Z</updated><entry><id>bvrch:Hy5wvP-gI</id><link rel="alternate" type="text/html" href="https://teletype.in/@bvrch/Hy5wvP-gI?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=bvrch"></link><title>Представление в памяти</title><published>2020-01-07T02:05:21.969Z</published><updated>2020-01-07T11:34:28.133Z</updated><summary type="html">Перемещая элементы в структурах данных общего назначения, мы копируем адрес. Т.е. всегда существует одна копия объекта, независимо от того, сколько раз он появляется в tuple/list/dict</summary><content type="html">
  &lt;p&gt;Перемещая элементы в структурах данных общего назначения, мы копируем адрес. Т.е. всегда существует одна копия объекта, независимо от того, сколько раз он появляется в tuple/list/dict&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;h3&gt;Int&lt;/h3&gt;
  &lt;pre&gt;x = 123&lt;/pre&gt;
  &lt;ul&gt;
    &lt;ul&gt;
      &lt;li&gt;refcount&lt;/li&gt;
      &lt;li&gt;address of type &lt;code&gt;-&amp;gt; type &amp;lt;int&amp;gt;&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;123&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h3&gt;String&lt;/h3&gt;
  &lt;pre&gt;s = &amp;#x27;Hello!&amp;#x27;&lt;/pre&gt;
  &lt;ul&gt;
    &lt;ul&gt;
      &lt;li&gt;refcount&lt;/li&gt;
      &lt;li&gt;address of type &lt;code&gt;-&amp;gt; type &amp;lt;str&amp;gt;&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;length&lt;/li&gt;
      &lt;li&gt;hash&lt;/li&gt;
      &lt;li&gt;flags&lt;/li&gt;
      &lt;li&gt;address = 0&lt;/li&gt;
      &lt;li&gt;&amp;#x27;Hello!&amp;#x27;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h3&gt;Tuple&lt;/h3&gt;
  &lt;pre&gt;t = (1, 2.0, &amp;#x27;Hello!&amp;#x27;)&lt;/pre&gt;
  &lt;ul&gt;
    &lt;ul&gt;
      &lt;li&gt;refcount&lt;/li&gt;
      &lt;li&gt;address of type &lt;code&gt;-&amp;gt; type &amp;lt;tuple&amp;gt;&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;length&lt;/li&gt;
      &lt;li&gt;address &lt;code&gt;-&amp;gt; int &amp;lt;1&amp;gt;&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;address &lt;code&gt;-&amp;gt; float &amp;lt;2.0&amp;gt;&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;address &lt;code&gt;-&amp;gt; str &amp;lt;&amp;#x27;Hello!&amp;#x27;&amp;gt;&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;blockquote&gt;&lt;em&gt;&lt;u&gt;Для последних трех адресов эта техника называется &lt;code&gt;indirection&lt;/code&gt;, т.е. хранятся просто адреса, а не объекты.&lt;/u&gt;&lt;/em&gt;&lt;/blockquote&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Вот как &lt;code&gt;tuple(10, 20)&lt;/code&gt; описан на C:&lt;/p&gt;
  &lt;pre&gt;typedef struct {
        Py_ssize_t ob_refcnt;
        struct _typeobject *ob_type;
        Py_ssize_t ob_size;
        PyObject *ob_item[2];     /* store a pointer to 10 and a pointer to 20 */
    } PyTupleObject;&lt;/pre&gt;
  &lt;p&gt;Заметьте, что &lt;code&gt;tuple&lt;/code&gt; включает в себя непосредственно два указателя на данные.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h3&gt;Dict&lt;/h3&gt;
  &lt;p&gt;За каждым dict - массив, в котором ключи хранятся на индексах согласно их hash value. Каждый слот должен хранить ключ и хэш.&lt;/p&gt;
  &lt;p&gt;Словарь обычно растёт увеличиваясь в 2 или в 4 раза. Расширение происходит, когда он заполнен на 2/3.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h3&gt;List&lt;/h3&gt;
  &lt;pre&gt;my_list = [1, 2, 3]&lt;/pre&gt;
  &lt;p&gt;Чтобы расти, списку необходимо переместиться, но объекты в Python не могут менять адрес. Спасает двойной &lt;code&gt;indirection&lt;/code&gt;.&lt;/p&gt;
  &lt;ul&gt;
    &lt;ul&gt;
      &lt;li&gt;refcount&lt;/li&gt;
      &lt;li&gt;address of type &lt;code&gt;-&amp;gt; type &amp;lt;list&amp;gt;&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;length = 3&lt;/li&gt;
      &lt;li&gt;array address &lt;code&gt;-&amp;gt; указывает на список из 4 элементов, один из которых пустой, о нём ниже&lt;/code&gt;&lt;/li&gt;
      &lt;ul&gt;
        &lt;li&gt;array len = 4&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;p&gt;Почему есть пустой элемент во &amp;quot;внутреннем&amp;quot; списке? Если бы не резервировалось для него место, то для каждого &lt;code&gt;append()&lt;/code&gt; надо было заноыо выделять место. Это дорого - каждый адрес эл-та копируется в новое место. &lt;/p&gt;
  &lt;p&gt;Релокация на каждом следующем append() суммируется:&lt;br /&gt;	- Чтобы добавить 2 эл-т в список нужно скопировать адрес 1 эл-та&lt;br /&gt;	- Чтобы добавить 3 эл-т в список нужно скопировать адрес 1 и 2 эл-тов&lt;br /&gt;И т.д.&lt;br /&gt;&lt;code&gt;append()&lt;/code&gt; на полный список запрашивает доп слоты для элементов. Списки в среднем используют 94% своих слотов, потребляя на 6% больше места, чем они используют. &lt;/p&gt;
  &lt;p&gt;Вот описание на C:&lt;/p&gt;
  &lt;pre&gt;   PyObject arr[2];              /* store a pointer to 10 and a pointer to 20 */

    typedef struct {
        Py_ssize_t ob_refcnt;
        struct _typeobject *ob_type;
        Py_ssize_t ob_size;
        PyObject **ob_item = arr; /* store a pointer to the two-pointer array */
        Py_ssize_t allocated;
    } PyListObject;&lt;/pre&gt;
  &lt;p&gt;Заметьте, что список включает в себя указатель ещё один уровень indirect, храня указатель на внешний массив с указателями.&lt;/p&gt;

</content></entry></feed>