当前位置: 首页 > article >正文

Unity 实现一个内存紧凑,高效,兼容度高,支持序列化的Map

前言

从Es5 js源码里搬过来的,起初没想到这么好用,直到用Unity内的Dictionary<K,V> 序列化的时候频频报错,iOS上也总有些乱七八糟的问题,在多人帧同步的项目中,由于桶结构的无序处理 ( Unity内部的字典是桶结构实现的) 所以禁止使用
随后我又尝试将STL里的红黑树搬过来用,结果性能还不如双列表。。。。, 果真是大道至简,越简单的反倒约好用

源码

支持,增删改查,适配所有序列化,Json, Protobuf,在帧同步项目中也可以安心使用,因为它是数组实现的,你可以通过内置的Foreach去遍历它,他是有序遍历的


public class Es5Map<K, V> where K : IEquatable<K>
{

    private List<K> keys = new List<K>();
    private List<V> values = new List<V>();


    public void Set( K key, V value )
    {
        keys.Add( key );
        values.Add( value );
    }

    public V Get( K key )
    {
        int index = keys.IndexOf( key );
        if ( index < 0 ) return default( V );
        return values[ index ];
    }

    public bool Has( K key ) => keys.Contains( key );

    public void Del( K key )
    {
        int index = keys.IndexOf( key );
        if ( index < 0 ) return;
        values.RemoveAt( index );
        keys.RemoveAt( index );
    }

    public int Count => keys.Count;

    public List<K> Keys => keys;

    public List<V> Values => values;

    public void Foreach( Action<K, V> action )
    {
        for ( int i = 0; i < keys.Count; i++ )
        {
            action( keys[ i ], values[ i ] );
        }
    }

}

先说说它的优点哈

  • 空间效率:双列表结构通过将键和值分开存储,可以减少空间占用,尤其是当字典的键和值比较简单时。如果每个键值对都存储在一个元组或其他结构中,这可能会增加内存开销。

  • 简单性:双列表的实现比较简单,通常只需要两个列表,分别存储键和值。这种结构不依赖复杂的数据结构,便于理解和实现。

  • 快速查找:如果使用一个列表存储键,而另一个列表存储对应的值,可以通过索引直接访问值,查询操作的时间复杂度通常为O(n),与哈希表相比稍微慢一些,但对小规模数据集或特定场景可能足够高效。

  • 顺序访问:双列表可以保持插入的顺序,对于某些应用场景,按插入顺序访问键值对是有用的,而哈希表通常无法保证顺序(除非是有序哈希表)。

  • 避免哈希冲突:哈希表实现字典时,哈希冲突是一个需要处理的问题,而双列表没有哈希函数的概念,因此没有哈希冲突问题。

再谈谈的缺点

查找效率和扩展性方面,相对于哈希表,性能会有所下降。

最后是我给的几点建议哈

  • 如果是多人同步的项目,要求不能使用字典,那么我推荐使用这个方案
  • 如果你的项目中存储的数据中需要用到字典结构,我推荐你使用这个方案,传统的字典会有各种序列化的问题
  • 如果你的项目只是一个本地的,且比较轻量,本地存储又用不到任何字典相关的数据,那推荐你使用传统字典,它查询的方式Hash更有效率

当然有想法的同学可以自行扩展哈,源码就是这么简单,想法全靠搬哈~


http://www.kler.cn/a/387808.html

相关文章:

  • 实战指南:理解 ThreadLocal 原理并用于Java 多线程上下文管理
  • 动态规划与贪心算法:核心区别与实例分析
  • 【go从零单排】Mutexes互斥锁
  • Redis安装(Windows环境)
  • linux rocky 9.4部署和管理docker harbor私有源
  • el-dialog 设置 水平垂直居中 高度不固定
  • 【K8S系列】Kubernetes 新创建的 Service 或 Pod 无法被发现问题【已解决】
  • 怎么禁止Ubuntu自动更新升级
  • 使用jmeter查询项目数据库信息,保存至本地txt或excel文件1108
  • Power Pivot、Power BI 和 SQL Server Analysis Services 的公式语言:DAX(数据分析表达式)
  • window11安装elasticsearch+Kibana
  • mac环境配置本地nfs服务
  • Chromium 中chrome.system.cpu扩展接口定义c++
  • 2024年下半年系统分析师论文
  • 【Linux】shell脚本:检测路径是否存在,如不存在则创建
  • Linux设置jar包开机自启
  • 闪耀CeMAT亚洲物流展,驭势科技发布第五代U-Drive®智驾系统
  • 使用docker部署Prometheus和Grafana去监控mysql和redis
  • 喜报!景联文科技成功通过DCMM数据管理能力成熟度二级认证
  • redis和数据库的数据一致性
  • Golang--文件操作
  • D64【python 接口自动化学习】- python基础之数据库
  • Redis常用的五大数据类型(列表List,集合set)
  • 计算机视觉实验四:特征检测与匹配
  • CSS外边距合并及解决办法
  • PL端:HDMI 输出实验