iOS - Objective-C 底层实现中的哈希表
1. 关联对象存储(AssociationsHashMap)
// 关联对象的哈希表实现
typedef DenseMap<const void *, ObjcAssociation> ObjectAssociationMap;
typedef DenseMap<DisguisedPtr<objc_object>, ObjectAssociationMap> AssociationsHashMap;class AssociationsManager {static AssociationsHashMap *_map; // 全局关联对象表void set(id object, const void *key, id value) {// 双层 map:对象 -> (key -> value)AssociationsHashMap::iterator i = _map->find(object);if (i != _map->end()) {ObjectAssociationMap &refs = i->second;refs[key] = ObjcAssociation(value);}}
};// 特点:
// 1. 双层哈希表结构
// 2. 使用 DenseMap 实现
// 3. 支持动态扩容
注意事项:
- 需要考虑内存开销
- 多层查找可能影响性能
- 需要正确管理关联对象的生命周期
2. 引用计数表(RefcountMap)
// SideTable 中的引用计数表
class SideTable {RefcountMap refcnts; // 存储对象的引用计数void retain(id obj) {RefcountMap::iterator it = refcnts.find(obj);if (it != refcnts.end()) {it->second += SIDE_TABLE_RC_ONE;}}
};typedef objc::DenseMap<DisguisedPtr<objc_object>, size_t> RefcountMap;// 特点:
// 1. 使用 DenseMap 实现
// 2. Key 使用伪装指针
// 3. 需要频繁访问和修改
注意事项:
- 需要保证原子性操作
- 性能要求高
- 内存管理要谨慎
3. 弱引用表(weak_table_t)
// 弱引用哈希表
struct weak_table_t {weak_entry_t *weak_entries; // 哈希数组size_t num_entries; // 实际条目数uintptr_t mask; // 容量掩码uintptr_t max_hash_displacement; // 最大哈希偏移weak_entry_t *get(id referent) {// 使用哈希查找size_t begin = hash_pointer(referent) & mask;size_t index = begin;size_t hash_displacement = 0;while (weak_entries[index].referent != referent) {index = (index + 1) & mask;if (index == begin) break;hash_displacement++;}return &weak_entries[index];}
};// 特点:
// 1. 开放寻址法处理冲突
// 2. 使用线性探测
// 3. 记录最大偏移量
注意事项:
- 需要控制装载因子,避免性能下降
- 删除元素时需要特殊处理,避免破坏探测链
- 扩容时需要重新哈希所有元素
4. 方法缓存(cache_t)
// 类的方法缓存
struct cache_t {struct bucket_t *_buckets; // 哈希表mask_t _mask; // 容量掩码mask_t _occupied; // 已使用数量IMP imp(SEL sel) {// 使用哈希查找方法实现bucket_t *b = buckets();mask_t m = mask();return findMethod(b, m, sel);}
};// 特点:
// 1. 采用散列函数直接寻址
// 2. 缓存最近使用的方法
// 3. 固定大小,满了就清空重建
注意事项:
- 缓存满时会清空重建,而不是扩容
- 性能敏感,需要快速查找
- 线程安全问题需要特别注意
5. 性能优化
// 使用 DenseMap 优化内存使用
template <typename T, typename U, typename V>
class DenseMap {// 1. 开放寻址法处理冲突pair<iterator, bool> insert(const T& key, const U& value) {// 查找空位置unsigned index = findEmptyBucket(key);// 插入数据Buckets[index] = make_pair(key, value);}// 2. 自动扩容void grow() {unsigned NewSize = size() * 2;rehash(NewSize);}
};
6. 使用特点
6.1 线程安全
// 访问 map 时加锁保护
spinlock_t& lock = SideTables()[obj].lock;
lock.lock();
// 操作 map
lock.unlock();
6.2 内存管理
// 定期清理
void cleanup() {// 遍历并清理无效条目for (iterator it = map.begin(); it != map.end();) {if (it->second.expired()) {it = map.erase(it);} else {++it;}}
}
6.3 哈希优化
// 优化的哈希函数
static inline uint32_t ptr_hash(const void *key) {uintptr_t k = (uintptr_t)key;return (uint32_t)(k ^ (k >> 7));
}
主要使用场景总结:
- 关联对象存储
- 引用计数管理
- 弱引用表实现
- 方法缓存
- 性能优化
使用特点:
- 多采用 DenseMap 实现
- 注重性能优化
- 考虑线程安全
- 自动内存管理
- 哈希冲突处理
7. 实现差异
7.1 冲突处理
// 开放寻址法
void insert(Key key, Value value) {size_t index = hash(key) & mask;while (table[index] != empty) {index = (index + 1) & mask; // 线性探测}table[index] = value;
}// 链地址法
void insert(Key key, Value value) {size_t index = hash(key) & mask;table[index].push_back(value); // 添加到链表
}
7.2 扩容策略
// weak_table_t 的扩容
void grow() {// 当使用率超过 3/4 时扩容if (num_entries >= capacity * 3/4) {resize(capacity * 2);}
}// cache_t 的重建
void rebuild() {// 缓存满时直接清空重建clear();allocate(capacity);
}
7.3 内存管理
// DenseMap 的内存管理
template <typename Key, typename Value>
class DenseMap {// 使用连续内存pair<Key, Value> *Buckets;// 自动扩容void grow() {reallocate(NumEntries * 2);}
};
8. 性能考虑
8.1 查找效率
// 方法缓存优化
IMP cache_t::imp(SEL sel) {// 使用位运算优化mask_t index = (mask_t)(uintptr_t)sel & _mask;return _buckets[index].imp();
}
8.2 空间效率
// weak_table_t 的空间优化
struct weak_entry_t {union {struct {weak_referrer_t *referrers; // 动态数组};struct {weak_referrer_t inline_referrers[WEAK_INLINE_COUNT]; // 内联存储};};
};
总结:
- 不同场景选择不同的哈希表实现
- 需要权衡时间和空间效率
- 要考虑线程安全问题
- 注意内存管理和性能优化
- 合理处理哈希冲突
- 选择适当的扩容策略
相关文章:
iOS - Objective-C 底层实现中的哈希表
1. 关联对象存储(AssociationsHashMap) // 关联对象的哈希表实现 typedef DenseMap<const void *, ObjcAssociation> ObjectAssociationMap; typedef DenseMap<DisguisedPtr<objc_object>, ObjectAssociationMap> AssociationsHashMa…...
什么是软件架构
什么是软件架构 程序员说,软件架构是要决定编写哪些C程序或OO类、使用哪些库和框架 程序经理说,软件架构就是模块的划分和接口的定义 系统分析员说,软件架构就是为业务领域对象的关系建模 配置管理员说,软件架构就是开发出来的…...
【Golang/nacos】nacos配置的增删查改,以及服务注册的golang实例及分析
前言 本文分析的实例来源于nacos在github上的开源仓库 nacos配置的增删查改 先具体来看一段代码,我将逐步分析每一段的作用 package mainimport ("fmt""time""github.com/nacos-group/nacos-sdk-go/clients""github.com/naco…...
RabbitMQ集群安装rabbitmq_delayed_message_exchange
1、单节点安装rabbitmq安装延迟队列 安装延迟队列rabbitmq_delayed_message_exchange可以参考这个文章: rabbitmq安装延迟队列-CSDN博客 2、集群安装rabbitmq_delayed_message_exchange 在第二个节点 join_cluster 之后,start_app 就会报错了 (CaseC…...
Linux UDP 编程详解
一、引言 在网络编程领域,UDP(User Datagram Protocol,用户数据报协议)作为一种轻量级的传输层协议,具有独特的优势和适用场景。与 TCP(Transmission Control Protocol,传输控制协议࿰…...
【2024年华为OD机试】(B卷,100分)- 计算最接近的数 (Java JS PythonC/C++)
一、问题描述 题目解析 我们需要找到一个下标 i,使得表达式 X[i] - X[i 1] - ... - X[i K - 1] 的结果最接近于数组的中位数。如果有多个 i 满足条件,则返回最大的 i。 关键点: 中位数计算: 将数组排序后,中位数…...
Pytorch 自学笔记(三):利用自定义文本数据集构建Dataset和DataLoader
Pytorch 自学笔记(三) 1. Dataset与DataLoader1.1 torch.utils.data.Dataset1.2 torch.utils.data.DataLoader Pytorch 自学笔记系列的第三篇。针对Pytorch的Dataset和DataLoader进行简单的介绍,同时,介绍如何使用自定义文本数据集…...
QT 使用QSqlTableModel对数据库进行创建,插入,显示
文章目录 效果图概述功能点代码分析初始数据插入数据数据显示 总结 效果图 概述 本案例用于对数据库中的数据进行显示等其他操作,其他表格筛选,过滤等功能可看此博客 框架:数据模型使用QSqlTableModel,视图使用QTableView&#x…...
如何学习Transformer架构
Transformer架构自提出以来,在自然语言处理领域引发了革命性的变化。作为一种基于注意力机制的模型,Transformer解决了传统序列模型在并行化和长距离依赖方面的局限性。本文将探讨Transformer论文《Attention is All You Need》与Hugging Face Transform…...
浅谈云计算22 | Kubernetes容器编排引擎
Kubernetes容器编排引擎 一、Kubernetes管理对象1.1 Kubernetes组件和架构1.2 主要管理对象类型 二、Kubernetes 服务2.1 服务的作用与原理2.2 服务类型 三、Kubernetes网络管理3.1 网络模型与目标3.2 网络组件3.2.1 kube-proxy3.2.2 网络插件 3.3 网络通信流程 四、Kubernetes…...
计算 SAMOut V3 在将词汇表从1万 增加到6千万的情况下能够减少多少参数
当我们将词汇表从 60,000,000(六千万)减少到 10,000 时,实际上是在缩小模型的词嵌入层及其共享的语言模型头(LM Head)的规模。这将导致参数量显著减少。我们可以通过以下步骤来计算具体的参数减少量。 参数量减少计算…...
03.选择排序
一、题目思路 选择排序是一种简单直观的排序算法。它的工作原理是:首先在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(或最大ÿ…...
02_登录窗口
新建场景 重命名为GameRoot 双击GameRoot进入新场景 同样摄像机清除格式 删除平行光并关闭渲染灯光的天空盒 新建空节点重命名为GameRoot GameRoot为游戏的根节点 在整个游戏中都不会被删除 在游戏的根节点下创建UI的根节点Canvas 创建一个空节点 作为UI根节点下的 登录场景UI…...
NodeJS | 搭建本地/公网服务器 live-server 的使用与安装
目录 介绍 安装 live-server 安装方法 安装后的验证 环境变量问题 Node.js 环境变量未配置正确 全局安装的 live-server 路径未添加到环境变量 运行测试 默认访问主界面 访问文件 报错信息与解决 问题一:未知命令 问题二:拒绝脚本 公网配置…...
SystemUI 实现音量条同步功能
需求:SystemUI 实现音量条同步功能 具体问题 以前在SystemUI 下拉框添加了音量条控制,目前发现在SystemUI下拉框显示状态的情况下, 按键或者底部虚拟导航点击音量加减时候,SystemUI音量条不更新。 如下图:两个Syste…...
嵌入式知识点总结 C/C++ 专题提升(一)-关键字
针对于嵌入式软件杂乱的知识点总结起来,提供给读者学习复习对下述内容的强化。 目录 1.C语言宏中"#“和"##"的用法 1.1.(#)字符串化操作符 1.2.(##)符号连接操作符 2.关键字volatile有什么含意?并举出三个不同的例子? 2.1.并行设备的硬件寄存…...
基础入门-传输加密数据格式编码算法密文存储代码混淆逆向保护安全影响
知识点: 1、传输格式&传输数据-类型&编码&算法 2、密码存储&代码混淆-不可逆&非对称性 一、演示案例-传输格式&传输数据-类型&编码&算法 传输格式 JSON XML WebSockets HTML 二进制 自定义 WebSockets:聊天交互较常…...
几个Linux系统安装体验(续): 统信桌面系统
本文介绍统信桌面系统(uos)的安装。 下载 下载地址: https://www.chinauos.com/resource/download-professional 下载文件:本文下载文件名称为uos-desktop-20-professional-1070-amd64.iso。 下载注意事项:可直接下…...
算法日记6.StarryCoding P52:我们都需要0(异或)
一、题目 二、题解: 1、对于这道题,题意为让我们寻找一个数x使得 b[i]a[i]^x, 并且b[1]^b[2]^b[3]^ b[4]^b[5]....0 2、我们把b[i]给拆开,可以得到 3、又因为^满足结合律,因此,可以把括号给拆开 4、接着…...
【网络协议】RFC3164-The BSD syslog Protocol
引言 Syslog常被称为系统日志或系统记录,是一种标准化的协议,用于网络设备、服务器和应用程序向中央Syslog服务器发送日志消息。互联网工程任务组(IETF)发布的RFC 3164,专门定义了BSD Syslog协议的规范和实现方式。通…...
HUNYUAN-MT 7B翻译终端Transformer架构解析:从原理到高效部署实践
HUNYUAN-MT 7B翻译终端Transformer架构解析:从原理到高效部署实践 最近在折腾一个多语言翻译项目,需要找一个既准又快、还能在本地部署的模型。兜兜转转,最后把目光锁定在了HUNYUAN-MT 7B上。这不仅仅是因为它70亿的参数量听起来很唬人&…...
Nunchaku FLUX.1 CustomV3批量处理技巧:高效生成1000+图像的方法
Nunchaku FLUX.1 CustomV3批量处理技巧:高效生成1000图像的方法 1. 引言 如果你正在使用Nunchaku FLUX.1 CustomV3生成图像,可能会遇到这样的困扰:每次只能生成几张图片,想要大批量产出内容时,需要反复手动操作&…...
BERT中文模型实战指南:从零开始搭建智能文本分类系统
BERT中文模型实战指南:从零开始搭建智能文本分类系统 1. 项目概述与准备工作 1.1 BERT模型简介 BERT(Bidirectional Encoder Representations from Transformers)是Google在2018年提出的预训练语言模型,它通过双向Transformer架…...
Meta推出Muse Spark,AI领域再掀波澜
Meta告别旧模型,Muse Spark闪亮登场周三,Meta宣布推出Muse系列的首个AI模型——Muse Spark,这标志着Meta彻底告别了之前在开源Llama模型系列上的工作。Llama系列模型在用户和独立大语言模型(LLM)排名中反响平平&#x…...
关于欧盟机械产品的CE-MD指令认证
机械MD指令(Machinery Directive 2006/42/EC)是欧盟针对机械产品制定的强制性安全法规,旨在确保机械在设计、制造和使用过程中的安全性,并实现欧盟内部市场的自由流通。该指令适用于绝大多数工业与民用机械设备,要求…...
Qwen2.5-Coder-1.5B功能体验:代码生成、推理、修复一站式解决
Qwen2.5-Coder-1.5B功能体验:代码生成、推理、修复一站式解决 1. 模型概览 Qwen2.5-Coder-1.5B是阿里云通义大模型团队推出的专业代码生成模型,属于Qwen2.5-Coder系列中的轻量级版本。该模型专为代码相关任务优化,在保持较小参数规模的同时…...
跨越版本鸿沟:Vivado 2022.2与Petalinux 2022.1协同构建HDMI显示系统
1. 为什么需要跨越版本鸿沟? 最近在做一个基于Zynq-7000的开发项目,需要实现HDMI显示功能。按照传统做法,很多人会选择Vivado 2018.3Petalinux 2018.3这套"黄金组合",毕竟网上教程多,资料全。但实际使用中我…...
00鲲鹏:华夏之光永存——架构师级·带领鲲鹏走进世界巅峰
鲲鹏:华夏之光永存——架构师级带领鲲鹏走进世界巅峰 系列总纲 在全球数字经济深度变革、算力技术成为国家核心战略竞争力的当下,国际算力芯片赛道竞争日趋白热化,技术壁垒、生态垄断、供应链安全成为国产算力发展的核心掣肘。当前行业内对鲲…...
圣女司幼幽-造相Z-Turbo快速部署:支持FP16精度的Z-Turbo LoRA推理优化
圣女司幼幽-造相Z-Turbo快速部署:支持FP16精度的Z-Turbo LoRA推理优化 本文介绍如何快速部署圣女司幼幽-造相Z-Turbo模型,这是一个基于Z-Image-Turbo LoRA版本的专业文生图模型,专注于生成《牧神记》中圣女司幼幽的高质量图像,并支…...
Emscripten构建优化指南:针对不同目标平台的终极优化策略
Emscripten构建优化指南:针对不同目标平台的终极优化策略 【免费下载链接】emscripten Emscripten: An LLVM-to-WebAssembly Compiler 项目地址: https://gitcode.com/gh_mirrors/em/emscripten Emscripten是一个强大的LLVM到WebAssembly编译器,它…...
