当前位置:网站首页>假如需要一百万个对象
假如需要一百万个对象
2020-11-09 23:53:00 【架构师修行之路】
设计背景
每个平台都会有用户这种基础数据的设计,作为最基础的用户,每个用户都有很多属性,比如性别,姓名,手机号等,每个用户还可以有类似经验值这样的荣誉系统,根据不同的经验值来对应不同的等级,不同的等级对应不同的荣誉UI,比如一级用户可能只显示一个星星,二级用户显示两颗星星,以此类推,类似于QQ等级的星星月亮太阳,这样的荣誉系统随着平台的不断壮大,可能会衍生出很多类型。那么问题来了,用户登录的时候就需要初始化用户的这些荣誉值,以星星数为例,类似于以下代码
public class Star
{
//等级
public int Level{get ;set ;}
//对应的星星数目
public int StarNumber{get ;set ;}
//对应的星星颜色
public int Color{get ;set ;}
... 其他属性
}
//用户信息
public class User{
public Star StarInfo{get ;set ;}
//...用户的其他属性
}
//初始化用户信息
User u=new User(){ StarInfo=new Star(){ Level=1, StarNumber=1,Color=1}};
每一个登录用户都会初始化一个Star属性来表示当前用户的Star信息,当有100万用户甚至更多用户同时在线的时候,内存中就实例化了同样数量的Star对象,以及其他类似的属性对象。这么多重复的对象难道不能优化吗?当然不是!!
问题分析
一个业务出现问题,首先要分析问题的所在。根据以上所说,问题的根本在于产生了大量的对象,首先每个用户对象都有自己独特的状态,这个基本上不可能分解优化,但是类似Star这样的属性就有优化途径了,这些荣誉属性一个最大的共同点就是不可变,换句话说,等级1的用户对应的Star信息是永远不会变的,永远是level=1,starnumber=1,color=1 等。基于这个不变性,我们可以把这个Star抽离出来,供所有等级1的用户使用,假设原来有10万等级1的用户,原来需要10万个对象,现在只需要一个对象,这可是天壤之别。
解决问题
基于以上问题分析,我们需要做的是把对象重复使用,只要是对象重复问题,基本上可以利用一个对象出口来解决问题,类似于以下的对象初始化工厂,但是要注意线程安全问题,因为同时请求并初始化对象的线程会有多个。
public class UserStarFac
{
static object objLock = new object();
static Dictionary<int, Star> UserStarMap = new Dictionary<int, Star>();
public static Star GetUserStar(int level)
{
//利用锁来防止实例化多次,当然这里可以优化
lock (objLock)
{
Star info = null; ;
if(!UserStarMap.TryGetValue(level, out info))
{
info = new Star() { Color = 1, Level = 1, StarNumber = 1 };
UserStarMap.Add(level,info);
}
return info;
}
}
}
编写简单测试程序
static void Main(string[] args)
{
int i = 0;
List<User> userList = new List<User>();
while (i < 100000)
{
// userList.Add(new User() { StarInfo=new Star() { Color=1, Level=1, StarNumber=1} });
userList.Add(new User() { StarInfo= UserStarFac .GetUserStar(1)});
i++;
}
Console.WriteLine("初始化完成");
Console.Read();
}
内存的测试结果:
不执行任何程序:占用内存:2.8 M
无优化初始化10万对象:占用内存:11 M
优化之后初始化10万对象:占用内存:7 M
居然一个小小的优化就减少了4M内存,不要小看这小小的4M,你要看的是比例,居然减少了将近 50%,真实业务中,可以进行这种优化的地方数不胜数,不知道你是否在乎呢?
这种大量重复对象的问题尤其是在游戏编程中经常存在,比如五子棋游戏,棋子的初始化,一个游戏大厅存在成千上百万对局,如果每个局中的棋子都初始化一个对象,那内存使用是相当可怕的,这种需要把通用的对象属性,不变的对象属性抽离出来,做共享是有必要的。
据说这种优化有一个学名:享元模式,没有必要记住名字,但需要记住原理和场景,必须要提一句:注意不变的对象才可以哦
更多精彩文章
版权声明
本文为[架构师修行之路]所创,转载请带上原文链接,感谢
https://my.oschina.net/caicaijun/blog/4710342
边栏推荐
- Validation failed for one or more entities. See ‘EntityValidationErrors’解决方法
- 获取List集合对象中某一列属性值
- 编码风格:Mvc模式下SSM环境,代码分层管理
- ES6, ES7, es8 Learning Guide
- Error running app: default activity not found solution
- 探访2020 PG技术大会
- SQL filter query duplicate columns
- Mongodb kernel source code implementation, performance tuning, best operation and maintenance practice series command processing module source code implementation 1
- crm系统的成本一般是多少?
- Prometheus installation configuration
猜你喜欢
随机推荐
Software engineering in code -- source code analysis of menu project
面试官:缓存穿透、缓存雪崩和缓存击穿是什么?
SQL intercepts the data before and after the '.'
价值超10亿美元的直播系统架构图是什么样子的?
Come and learn! Development Guide for personalized recommendation system (with internet disk link)
Gets the property value of a column in the list collection object
获取List集合对象中某一列属性值
消防知识线上答题活动小程序复盘
DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
JMeter的简单使用
lodash.js源码-flatten
pytorch训练GAN时的detach()
没有磁盘空间 No space left on device
Usage of [:] and [::] in Python
Gets the property value of a column in the list collection object
One image can hold 16x16 words! ——Transformers for large scale image scaling recognition (a brief review of ICLR 2021 papers)
痞子衡嵌入式:RT-UFL - 一个适用全平台i.MXRT的超级下载算法设计
CUDA_ Register and local memory
编码风格:Mvc模式下SSM环境,代码分层管理
代码中的软件工程--对menu项目的源码分析