python解释器[源代码层面]

news2024/9/20 7:51:22

1 PyDictObject

在c++中STL中的map是基于 RB-tree平衡二元树实现,搜索的时间复杂度为O(log2n)

Python中PyDictObject是基于散列表(散列函数)实现,搜索时间最优为O(1)

1.1 散列列表

问题:散列冲突:多个元素计算得到相同的哈希值

解决方法:

(1)开链法

(2)开放地址法:二次探测法(python中用的)

通过增加一个二次函数形式的偏移量来查找下一个空闲位置。哈希表的大小为m,一个元素的初始位置由哈希函数 h(x)决定。若发生冲突,则将元素插入到位置 (h(x)+i^2)mod  m处,其中i是探测的步数。探测序列是一个二次序列,例如:1^2,(-1)^2,2^2,(-2)^2在表中寻找下一个可用位置。

从一个位置出发可依次到达多个位置,形成“冲突探测链”(注意删除链上元素导致的断链,采用伪删除技术。)

1.2 定义

typedef struct {
    /* Cached hash code of me_key. */
    Py_hash_t me_hash; //存储me_key的散列值,维护该值是避免每次查询时重新计算
    PyObject *me_key;
    PyObject *me_value; /* This field is only meaningful for combined tables */
} PyDictKeyEntry;

entry生存周期的四种状态

  1. unused态:me_key/me_value都是null(entry在初始化的时候)。
  2. Active态:entry存储了键值对的状态。
  3. Dummy态:me_key指向dummy对象(伪删除)。
  4. Pending态:键!=空,值=空(仅拆分),尚未插入到拆分表中。
/* The ma_values pointer is NULL for a combined table
 * or points to an array of PyObject* for a split table*/
typedef struct {
    PyObject_HEAD
    Py_ssize_t ma_used;    /*字典中项的数量*/
#ifdef Py_BUILD_CORE
    uint64_t ma_version_tag; /*表示字典中对象版本*/
#else
    Py_DEPRECATED(3.12) uint64_t ma_version_tag; /*表示字典中对象版本*/
#endif
    /*若ma_values为空,则表是结合的,键与值都存储在ma_keys中*/
    /*若ma_values不为空,则表是分开的,键存储在ma_keys中,值存储在ma_values*/
    PyDictKeysObject *ma_keys; /*实际存储数据的哈希表,具体有两种存储方式*/
    PyDictValues *ma_values; //根据两种存储方式决定是否有值
} PyDictObject;
struct _dictkeysobject {
    Py_ssize_t dk_refcnt;//引用计数器数目

    /* Size of the hash table (dk_indices). It must be a power of 2. */
    uint8_t dk_log2_size; //这张哈希表的大小(最大存储的元素的数目)

    /* Size of the hash table (dk_indices) by bytes. */
    uint8_t dk_log2_index_bytes; //哈希表大小的字节数

    /* Kind of keys */
    uint8_t dk_kind; //类型的键

    /* Version number -- Reset to 0 by any modification to keys */
    uint32_t dk_version; //版本号

    /* Number of usable entries in dk_entries. */
    Py_ssize_t dk_usable; //在dk_entries中可用的数量

    /* Number of used entries in dk_entries. */
    Py_ssize_t dk_nentries; //在dk_entries中使用的数量(8个字节)

    /* Actual hash table of dk_size entries. It holds indices in dk_entries,
       or DKIX_EMPTY(-1) or DKIX_DUMMY(-2).

       Indices must be: 0 <= indice < USABLE_FRACTION(dk_size).

       The size in bytes of an indice depends on dk_size:

       - 1 byte if dk_size <= 0xff (char*)
       - 2 bytes if dk_size <= 0xffff (int16_t*)
       - 4 bytes if dk_size <= 0xffffffff (int32_t*)
       - 8 bytes otherwise (int64_t*)

       Dynamically sized, SIZEOF_VOID_P is minimum. */
    char dk_indices[];  /* 索引,一个元素一个字节 */

    /* "PyDictKeyEntry or PyDictUnicodeEntry dk_entries[USABLE_FRACTION(DK_SIZE(dk))];" array follows:
       see the DK_ENTRIES() macro */
};

1.3 python3.6+的存储方法

  1. 第一条key-value,计算inx=hash(key)%num,num是索引表长,索引表中存放着对于enries的偏移量。
  2. 依据indices[inx]的值(偏移量)存放Hash value=hash(key)、key、value
  3. 若该位置已经有元素,则根据冲突解决策略找下一个空闲的索引。
  4. 查找键的时候同样流程,并比较键与值来确定是否需要所需元素。

---------------后续有必要再继续写---------------------------------------------------

2 解释器

2.1组成

编译器:得到字节码的编译结果(import py文件、import compileall、内建函数compile后会得到.pyc文件)

虚拟机:执行字节码

执行环境:字典对象,维护运行过程中动态创建的变量和变量名与变量值的映射。

2.2执行脚本流程

1.完成模块的加载和链接

2.将源代码编译为PyCodeObject对象,并将其写入内存,使得CPU快速读取,加快程序运行

注:字节码与PyCodeObject对象的关系?

        PyCodeObject对象包含字符串,常量值,操作(字节码)等静态信息(运行时存储在PyCodeObject对象中,运行结束后存储在pyc文件)

3.从内存空间中读取指定并执行(虚拟机完成)

编译器与虚拟机在:python .dll

4.程序结束后根据调用的操作指令决定是否也将PyCodeObject对象写入硬盘,即.pyc文件或.pyo文件。

5.下一次再执行该脚本,则先检查本地是否有上述.pyc文件。如有,则执行。

2.3PyCodeObject

struct PyCodeObject{                                                    \
    PyObject_VAR_HEAD                                                          \
                                                                               \
    /* Note only the following fields are used in hash and/or comparisons      \
     *                                                                         \
     * - co_name                                                               \
     * - co_argcount                                                           \
     * - co_posonlyargcount                                                    \
     * - co_kwonlyargcount                                                     \
     * - co_nlocals                                                            \
     * - co_stacksize                                                          \
     * - co_flags                                                              \
     * - co_firstlineno                                                        \
     * - co_consts                                                             \
     * - co_names                                                              \
     * - co_localsplusnames                                                    \
     * This is done to preserve the name and line number for tracebacks        \
     * and debuggers; otherwise, constant de-duplication would collapse        \
     * identical functions/lambdas defined on different lines.                 \
     */                                                                        \
                                                                               \
    /* These fields are set with provided values on new code objects. */       \
                                                                               \
    /* The hottest fields (in the eval loop) are grouped here at the top. */   \
    PyObject *co_consts;           /* list (constants used) */                 \
    PyObject *co_names;            /* list of strings (names used) */          \
    PyObject *co_exceptiontable;   /* Byte string encoding exception handling  \
                                      table */                                 \
    int co_flags;                  /* CO_..., see below */                     \
                                                                               \
    /* The rest are not so impactful on performance. */                        \
    int co_argcount;              /* #arguments, except *args */               \
    int co_posonlyargcount;       /* #positional only arguments */             \
    int co_kwonlyargcount;        /* #keyword only arguments */                \
    int co_stacksize;             /* #entries needed for evaluation stack */   \
    int co_firstlineno;           /* first source line number */               \
                                                                               \
    /* redundant values (derived from co_localsplusnames and                   \
       co_localspluskinds) */                                                  \
    int co_nlocalsplus;           /* number of local + cell + free variables */ \
    int co_framesize;             /* Size of frame in words */                 \
    int co_nlocals;               /* number of local variables */              \
    int co_ncellvars;             /* total number of cell variables */         \
    int co_nfreevars;             /* number of free variables */               \
    uint32_t co_version;          /* version number */                         \
                                                                               \
    PyObject *co_localsplusnames; /* tuple mapping offsets to names */         \
    PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte    \
                                     per variable) */                          \
    PyObject *co_filename;        /* unicode (where it was loaded from) */     \
    PyObject *co_name;            /* unicode (name, for reference) */          \
    PyObject *co_qualname;        /* unicode (qualname, for reference) */      \
    PyObject *co_linetable;       /* bytes object that holds location info */  \
    PyObject *co_weakreflist;     /* to support weakrefs to code objects */    \
    _PyCoCached *_co_cached;      /* cached co_* attributes */                 \
    uint64_t _co_instrumentation_version; /* current instrumentation version */  \
    _PyCoMonitoringData *_co_monitoring; /* Monitoring data */                 \
    int _co_firsttraceable;       /* index of first traceable instruction */   \
    /* Scratch space for extra data relating to the code object.               \
       Type is a void* to keep the format private in codeobject.c to force     \
       people to go through the proper APIs. */                                \
    void *co_extra;                                                            \
    char co_code_adaptive[(SIZE)];                                             \
}

1.一个命名空间对应一个PyCodeObject对象。

2.类、函数、module都对应一个独立的命名空间(存在嵌套关系)。

2.4pyc文件

pyc文件=magic number( 区别python版本)+pyc文件的最后一次修改时间(再次加载时判断是否修改过)+PyCodeObject对象。

2.5创建pyc文件的具体过程(把PyCodeObject对象写入文件)

-------------------------待写

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2083701.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为IS-IS实验及配置

AR1配置 #进入ISIS进程 isis 1 #配置设备类型为Level-1is-level level-1 #定义区域和System-ID等信息network-entity 49.0001.0010.0000.0001.00 #ISIS邻居命名is-name AR1 #接口配置IP和启用ISIS interface GigabitEthernet0/0/0ip address 10.1.12.1 255.255.255.0 isis ena…

【C++】C++ STL 探索:String的使用与理解

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶 这篇文章将带大家深入探讨C STL中的string使用与理解。在接下来的几篇文章中&#xff0c;我们将介绍…

WT2605C蓝牙语音芯片:引领糖尿病管理智能化,优化血糖仪音频与蓝牙传输方案

开发背景 全球糖尿病成人患者数量截至2021年约为5.37亿&#xff0c;并预计到2045年将增长至7.83亿。患病率不仅随年龄增长&#xff0c;还展现出明显的地域差异&#xff0c;例如巴基斯坦的患病率最高。此外&#xff0c;老年人群和某些特定地区的居民面临更高的糖尿病风险。 语音…

Leetcode 22. 括号生成 回溯 C++实现

Leetcode 22.括号生成 问题&#xff1a;数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且有效的括号组合。 算法&#xff1a; 创建返回数组 ans &#xff0c;和临时变量 path 。 当左括号数量 open 小于应填括号数 n 时&#…

【Python机器学习】NLP词中的数学——主题建模

目录 齐普夫定律 相关度排序 工具 其他工具 Okapi BM25 在文档向量中&#xff0c;词计数是有用的&#xff0c;但是纯词计数&#xff0c;即使按照文档长度进行归一化处理&#xff0c;也不能告诉我们太多该词在当前文档相对于语料库中其他文档的重要度信息。如果能弄清楚这些…

carla unreal engine源码:如何创建radar可视化探测锥

文章目录 前言一、C实现方法1、DrawDebugCone函数2、carla工程修改3、make launch4、探测锥验证 二、蓝图实现方法1、创建并打开蓝图2、打开蓝图事件图表3、绘制蓝图事件4、编译再运行 前言 1、在自动驾驶仿真调试以及测试过程中&#xff0c;我们经常会用到雷达的探测锥&#…

SkyWalking部署(监控系统)

简介 SkyWalking 是一个开源的应用性能监控 (APM) 和可观测性平台&#xff0c;旨在帮助开发者、运维人员和架构师监控、诊断和优化微服务架构中的应用。SkyWalking 提供了一套完整的工具链&#xff0c;用于收集、分析和可视化应用的性能指标、追踪和日志数据。 SkyWalking 的…

wpf prism 《2》、导航

》》》主程序 using Prism.Commands; using Prism.Mvvm; using Prism.Navigation; using Prism.Navigation.Regions; using System;namespace BlankApp2.ViewModels {public class MainViewModel : BindableBase{private string _title "Prism Application";public…

数据结构《排序》

在之前数据结构之算法复杂度章节中我们学习了复杂度相关的概念&#xff0c;这就使得懂得如何来区分算法的好坏&#xff0c;在之前C语言专题中在指针的学习时我们了解了冒泡排序&#xff0c;之后再数据结构的二叉树章节中我们又学习了堆排序&#xff0c;其实排序不止这两种&…

搜剧平台源码 可一键转存他人链接

简介 1、一键转存他人链接&#xff1a;就是将别人的分享链接转为你自己的 2、转存心悦搜剧资源&#xff1a;就是将心悦搜剧平台上的所有资源都转成你自己的 3、每日自动更新&#xff1a;自动转存每天的资源并入库 前端uin-app&#xff0c;后端PHP&#xff0c;兼容微信小程序…

基于vue框架的博物馆预约网站的设计与实现8k352(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,类别,博物馆,预约信息,馆藏精品 开题报告内容 基于Vue框架的博物馆预约网站的设计与实现开题报告 一、开题报告名称 基于Vue框架的博物馆预约网站的设计与实现 二、研究背景与意义 随着信息技术的飞速发展和人们生活水平的日益…

QT5.14.2编译有界面的DLL供C#Winform程序调用步骤

目标&#xff1a;公司要设计一套软键盘程序给到WinForm程序调用、因此需要封装QT的软键盘程序给到C#调用&#xff0c;跟C#调用MFC的DLL代码差不多&#xff0c;感觉就是封装了一下QT的代码成为MFC格式的。 步骤&#xff1a;1、新建QT对应的库项目、编译器使用MSVC2017 64位、编…

Apache RocketMQ 中文社区全新升级丨阿里云云原生 7 月产品月报

云原生月度动态 云原生是企业数字创新的最短路径。 《阿里云云原生每月动态》&#xff0c;从趋势热点、产品新功能、服务客户、开源与开发者动态等方面&#xff0c;为企业提供数字化的路径与指南。 趋势热点 &#x1f947; 通义灵码入选 2024 世界人工智能大会最高荣誉「镇…

Beyond Compare忽略特定格式文本,忽略匹配正则表达式

一 概述 文本对比时忽略某些文本。比如有些生成的文件需要做差异对比&#xff0c;除了内容有差异外&#xff0c;自动生成的ID也不同&#xff0c;想忽略这些ID。特别是文件内容比较多的时候。 如上图&#xff0c;其中UUID“*”的部分我想忽略。 二 方法 方法1 通过Beyond Co…

开放大世界的碰撞与物理

众所周知&#xff0c;物理开销一直是 CPU 的一个大头&#xff0c;而且还很容易出问题。对于开放世界&#xff0c;该如何进行物理运算&#xff0c;以及采用什么方案计算碰撞。 本文针对这个问题做了一些细微的研究&#xff0c;算是对 Unity 下的解决方案有了一个大致的方向。 1、…

《“草莓”引领风潮:全能AI与专业型AI的未来市场较量》

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Vmware下安装Rocky Linux9.4

Rocky Linux简介 Rocky Linux是一个开源、社区拥有和管理、免费的企业Linux发行版&#xff0c;提供强大的生产级平台。可作为CentOS停止维护后的替代方案。 下载Rocky Linux 下载地址 Download - Rocky Linux 根据电脑实际情况选择对应版本的Linux&#xff0c;这里下载AMD/In…

springboot在线办公小程序论文源码调试讲解

第二章 技术介绍 2.1 B/S结构 随着软件系统的不断改进和升级&#xff0c;B/S结构产品更为方便的特征体现地十分明显。对于一个中等偏大的公司来说&#xff0c;如果系统管理员每天要在很多台电脑之间来回查看&#xff0c;不断奔走&#xff0c;那么效率和工作量就会变得很低&…

HSE软件组件有哪些?如何实现HSE与主机的通信(同步/异步)?如何使用HSE提供的安全服务?

《S32G3系列芯片——Boot详解》系列——HSE软件组件有哪些&#xff1f;如何实现HSE与主机的通信&#xff08;同步/异步&#xff09;&#xff1f;如何使用HSE提供的安全服务&#xff1f; 一、HSE子系统软件组件1.1 NXP交付用户的HSE固件内容1.2 HSE固件提供的安全服务1.3 HSE固件…

代码随想录刷题day15丨110.平衡二叉树,257. 二叉树的所有路径, 404.左叶子之和 ,222.完全二叉树的节点个数

代码随想录刷题day15丨110.平衡二叉树&#xff0c;257. 二叉树的所有路径&#xff0c; 404.左叶子之和 &#xff0c;222.完全二叉树的节点个数 1.题目 1.1平衡二叉树&#xff08;优先掌握递归&#xff09; 题目链接&#xff1a;110. 平衡二叉树 - 力扣&#xff08;LeetCode&a…