玩家属性同步优化-脏数据标记(位运算、数组、stl之bitset)

把大神的帖子中一部分摘抄出来,结合自己写的位运算代码和循环代码(数组遍历)进行性能测试分析并给出结果。 摘自: https://www.gameres.com/827195.html

本文适用于所有脏标记遍历功能,提升性能几倍,本文以游戏中玩家的属性同步作为例子进行介绍。

先说性能分析结果:一般玩家属性列表也就120个够用了,其中常用的攻击,防御,血蓝等,不超过20个。每0.5秒同步一次,那么变化的常用属性更少。

当变化10个属性,位运算性能提升6倍,20个时4倍,如图所示:

总结:位运算效率高,并且把常用属性定义为低位效率更高。 其次是数组(原因是遍历),再其次是set(影响原因是hash函数、hash扩容、二叉树节点转换),最差是stl之bitset(原因:本质也是数组)

优化前的循环算法(数组):

 1 const int N = 128;
 2 class BitSet
 3 {
 4     public:
 5         BitSet()
 6         {
 7             memset(m_szBits,0,sizeof(m_szBits));
 8             m_bBitsDirty = false;
 9         }
10         int Set(size_t i)
11         {
12             if(i >= 0 && i < N)
13             {
14                 ++m_szBits[i];
15 
16                 m_bBitsDirty = true;
17 
18             }
19             return 0;
20         }
21         int Get(size_t i) const
22         {
23             if(i >= 0 && i < N)
24             {
25                 return m_szBits[i] > 0;
26             }
27             return 0;
28         }
29         void Clean()
30         {
31             memset(m_szBits,0,sizeof(m_szBits));
32             m_bBitsDirty = false;
33         }
34         bool IsDirty() const
35         {
36             return m_bBitsDirty;
37         }
38     private:
39         char * m_szBits[N];
40         bool m_bBitsDirty;
41 };
View Code

优化后的位运算:

 1 const int nLLLeng = 64;
 2 class NewBitSet
 3 {
 4     public:
 5         NewBitSet():llLow(0ull),llHight(0ull)
 6     {
 7     }
 8         void Set(size_t i)
 9         {
10             if(i > 0 && i < nLLLeng)
11             {
12                 llLow |= 1ull << i;
13             }
14             else if (i < nLLLeng * 2)
15             {
16                 llHight |= 1ull << (i & 0x3F);    // 0x3F 是64的16进制,这样做是相当于减64
17             }
18         }
19         void GetAllDirty(int * arrDirty, int & nMaxCount) const
20         {
21             unsigned long long nllLowTemp = llLow;
22             unsigned long long nllHightTemp = llHight;
23             nMaxCount = -1;
24             while (nllLowTemp)
25             {
26                 arrDirty[++nMaxCount] = __builtin_ffsll(nllLowTemp) - 1;
27                 nllLowTemp &= (nllLowTemp - 1);
28             }
29             while (nllHightTemp)
30             {
31                 arrDirty[++nMaxCount] = __builtin_ffsll(nllHightTemp) - 1 + nLLLeng;
32                 nllHightTemp &= (nllHightTemp - 1);
33             }
34         }
35         void Clean()
36         {
37             llLow = llHight = 0ull;
38         }
39 
40         bool IsDirty() const
41         {
42             return llLow || llHight;
43         }
44     private:
45         unsigned long long int llLow;
46         unsigned long long int llHight;
47 };
View Code

测试用例:

  1 #include <iostream>
  2 #include <sys/time.h>
  3 #include<stdlib.h>
  4 #include <algorithm>
  5 #include <math.h>
  6 #include <stdio.h>
  7 #include<vector>
  8 #include<map>
  9 #include <string.h>
 10 using namespace std;
 11 const int N = 128;
 12 class BitSet
 13 {
 14     public:
 15         BitSet()
 16         {
 17             memset(m_szBits,0,sizeof(m_szBits));
 18             m_bBitsDirty = false;
 19         }
 20         int Set(size_t i)
 21         {
 22             if(i >= 0 && i < N)
 23             {
 24                 ++m_szBits[i];
 25 
 26                 m_bBitsDirty = true;
 27 
 28             }
 29             return 0;
 30         }
 31         int Get(size_t i) const
 32         {
 33             if(i >= 0 && i < N)
 34             {
 35                 return m_szBits[i] > 0;
 36             }
 37             return 0;
 38         }
 39         void Clean()
 40         {
 41             memset(m_szBits,0,sizeof(m_szBits));
 42             m_bBitsDirty = false;
 43         }
 44         bool IsDirty() const
 45         {
 46             return m_bBitsDirty;
 47         }
 48     private:
 49         char * m_szBits[N];
 50         bool m_bBitsDirty;
 51 };
 52 
 53 
 54 const int nLLLeng = 64;
 55 class NewBitSet
 56 {
 57     public:
 58         NewBitSet():llLow(0ull),llHight(0ull)
 59     {
 60     }
 61         void Set(size_t i)
 62         {
 63             if(i > 0 && i < nLLLeng)
 64             {
 65                 llLow |= 1ull << i;
 66             }
 67             else if (i < nLLLeng * 2)
 68             {
 69                 llHight |= 1ull << (i & 0x3F);    // 0x3F 是64的16进制,这样做是相当于减64
 70             }
 71         }
 72         void GetAllDirty(int * arrDirty, int & nMaxCount) const
 73         {
 74             unsigned long long nllLowTemp = llLow;
 75             unsigned long long nllHightTemp = llHight;
 76             nMaxCount = -1;
 77             while (nllLowTemp)
 78             {
 79                 arrDirty[++nMaxCount] = __builtin_ffsll(nllLowTemp) - 1;
 80                 nllLowTemp &= (nllLowTemp - 1);
 81             }
 82             while (nllHightTemp)
 83             {
 84                 arrDirty[++nMaxCount] = __builtin_ffsll(nllHightTemp) - 1 + nLLLeng;
 85                 nllHightTemp &= (nllHightTemp - 1);
 86             }
 87         }
 88         void Clean()
 89         {
 90             llLow = llHight = 0ull;
 91         }
 92 
 93         bool IsDirty() const
 94         {
 95             return llLow || llHight;
 96         }
 97     private:
 98         unsigned long long int llLow;
 99         unsigned long long int llHight;
100 };
101 
102 int nPrintCount = 1;
103 
104 void DirtyBit(int nRandCount)
105 {
106     NewBitSet tDirty;
107     int nRand = 0;
108     //srand((unsigned)time(0));
109     for (int i = 0; i < nRandCount;i++)
110     {
111     //    nRand = rand()%126 + 1;
112         tDirty.Set(i+1);
113     }
114     if (!tDirty.IsDirty())
115     {
116         return;
117     }
118     int arrDirty[nLLLeng * 2] = {0};
119     //同步自己执行次数
120     int nMaxCount = 0;
121     tDirty.GetAllDirty(arrDirty, nMaxCount);
122     nMaxCount = 0;
123     //同步WS执行次数
124     tDirty.GetAllDirty(arrDirty, nMaxCount);
125 
126     int nNotPrint = 0;
127     for (int i = 0; i< nMaxCount; i++)
128     {
129         nNotPrint = arrDirty[i];
130     }
131     tDirty.Clean();
132 }
133 
134 void DirtyArr(int nRandCount)
135 {
136     BitSet tDirty;
137     int nRand = 0;
138 //    srand((unsigned)time(0));
139     for (int i = 0; i < nRandCount;i++)
140     {
141 //        nRand = rand()%126 + 1;
142         tDirty.Set(i+1);
143     }
144     if (tDirty.IsDirty())
145     {
146         int arrDirty[N] = {0};
147         int nMaxCount = -1;
148         //同步自己执行次数
149         for (int i = 0; i< N; ++i)
150         {
151             if (tDirty.Get(i))
152             {
153                 arrDirty[++nMaxCount] = i;
154             }
155         }
156         //同步WS执行次数
157         nMaxCount = -1;
158         for (int i = 0; i< N; ++i)
159         {
160             if (tDirty.Get(i))
161             {
162                 arrDirty[++nMaxCount] = i;
163             }
164         }
165         int nNotPrint = 0;
166         for (int i = 0; i< nMaxCount + 1; i++)
167         {
168             nNotPrint = arrDirty[i];
169         }
170     }
171 
172     tDirty.Clean();
173 }
174 
175 int main()
176 {
177     float time_use=0;
178     struct timeval start;
179     struct timeval end;
180     int nTestCount =100 ;
181     gettimeofday(&start,NULL);
182 
183     nPrintCount = 1;
184     //处理过程--开始
185     for (int i = 0; i< 10000; ++i)
186     {
187         DirtyBit(nTestCount);
188     }
189     //处理过程--结束
190 
191     cout<<endl;
192     gettimeofday(&end,NULL);
193     time_use=(end.tv_sec-start.tv_sec)*1000000+(end.tv_usec-start.tv_usec);//微秒
194     printf("time_use is %.10f\n",time_use);
195 
196     nPrintCount = 1;
197     gettimeofday(&start,NULL);
198     //处理过程--开始
199     for (int i = 0; i< 10000; ++i)
200     {
201         DirtyArr(nTestCount);
202     }
203     //处理过程--结束
204 
205     cout<<endl;
206     gettimeofday(&end,NULL);
207 
208     time_use=(end.tv_sec-start.tv_sec)*1000000+(end.tv_usec-start.tv_usec);//微秒
209     printf("time_use is %.10f\n",time_use);
210     return 0;
211 }
View Code

 

转载于:https://www.cnblogs.com/workharder/p/11526200.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值