zoukankan      html  css  js  c++  java
  • 创建一个比微软性能更好空间更少的GUID

    几年前写过C++版本并测试都没问题,见我以前的链接:http://blog.csdn.net/monster877/article/details/23067189
    现在翻译成C#版本,创建10万个GUID的时间只需要3ms左右,C++的或许速度更快,具体算法如下:

    1
    using System; 3 using System.Collections.Generic; 4 using System.Diagnostics; 5 using System.Linq; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace Test 10 { 11 12 //自定义GUID 13 public class MyGuid 14 { 15 /** 16 本程序可以生成64位全游戏大世界全局唯一ID,适合在分布式服务器集群中产生唯一ID 17  特点比微软自带的GUID要节省一倍的空间,即只需要64位的int即可,因此基本上在游戏服务器领域可以抛弃微软的那个GUID了 18 支持每秒生成4096个,在此条件基础上这辈子都不会产生相同的ID 19 20 由 时间戳+服务器区号+平台号+本地递增序号 组成 21 22 时间戳 32bit 23 服务器区号 12bit 24 平台号 8bit 25 递增序号 12bit 26 */ 27 private static ulong c_mark_time_stamp = 0xffffffff00000000;/*时间戳掩码*/ 28 private static ulong c_mark_district = 0x00000000fff00000;/*服务器区号掩码*/ 29 private static ulong c_mark_plat = 0x00000000000ff000;/*服务器里的平台号掩码*/ 30 private static ulong c_mark_base = 0x0000000000000fff;/*本地ID编号掩码*/ 31 private static uint c_baseId = 0;/*本地ID*/ 32 private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 33 34 //生成整个世界里全局唯一的ID district:服务器区号,platform:平台号 [如果游戏只接一个平台,则此平台号可以是服务器集群里的服务器类型编号] 35 public static ulong NewGuid(uint platform, uint district) 36 { 37 ulong timeStamp = (ulong)(DateTime.UtcNow- Jan1st1970).TotalSeconds;//获取自古以来的时间戳 38 ulong newId = ((timeStamp << 32) & c_mark_time_stamp) | ((district << 20) & c_mark_district) | ((platform << 12) & c_mark_plat) | (c_baseId & c_mark_base); 39 40 c_baseId++; 41 42 return newId; 43 } 44 } 45 class Program 46 { 47 static void Main(string[] args) 48 { 49 ulong guid = MyGuid.NewGuid(1, 1); 50 } 51 } 52 }

    有人嫌每秒只能4096个少了,可以改成这样就可以每秒100多万了:

         public class MyGuid
            {
                /**
                  本程序可以生成64位全游戏大世界全局唯一ID,适合在分布式服务器集群中产生唯一ID
                 特点比微软自带的GUID要节省一倍的空间,即只需要64位的int即可,因此基本上在游戏服务器领域可以抛弃微软的那个GUID了
                  支持每秒生成1048576个,在此条件基础上这辈子都不会产生相同的ID
    
                    由 时间戳+大区号+小区号+本地递增序号 组成
    
                    时间戳 32bit
                    大区号 4bit
                    小区号 8bit
                    递增序号 20bit 
    
                    支持大区16个,每个大区下支持256个小区,每个小区里支持每秒生成1048576个唯一ID
                  */
                private static ulong c_mark_time_stamp = 0xffffffff00000000;/*时间戳掩码*/
                private static ulong c_mark_big_district = 0x00000000f0000000;/*大区号掩码*/
                private static ulong c_mark_small_district = 0x000000000ff00000;/*小区号掩码*/
                private static ulong c_mark_base = 0x00000000000fffff;/*本地ID编号掩码*/
                private static uint c_baseId = 0;/*本地ID*/
                private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    
                public static ulong NewGuid(uint bigDistrict, uint smallDistrict)
                {
                    ulong timeStamp = (ulong)(DateTime.UtcNow - Jan1st1970).TotalSeconds;//获取自古以来的时间戳
                    ulong newId = ((timeStamp << 32) & c_mark_time_stamp) | ((bigDistrict << 28) & c_mark_big_district) | ((smallDistrict << 20) & c_mark_small_district) | (c_baseId & c_mark_base);
    
                    c_baseId++;
    
                    return newId;
                }
            }
    最后再贴一下适合大世界的版本,支持根据guid反推所在服务器信息哦
        //服务器类型
        public enum ServerType
        {
            DB = 1,     //数据库服务器
            Logic = 2,  //逻辑服务器
            World = 3,  //世界服务器
            AC = 4,     //平台认证服务器
            Proxy = 5,  //网关服务器
            Center = 6, //中心服务器
            Record = 7, //记录服务器
        }
        //自定义GUID
        public class MyGuid
        {
            /**
              本程序可以生成64位全游戏大世界全局唯一ID,适合在分布式服务器集群中产生唯一ID,也适合分区分服的服务器,可自由更改掩码与占位调节
             特点比微软自带的GUID要节省一倍的空间,即只需要64位的int即可,因此基本上在游戏服务器领域可以抛弃微软的那个GUID了
              支持每秒生成65536个,在此条件基础上这辈子都不会产生相同的ID
    
              由 时间戳+服务器类型号+服务器ID号+本地递增序号 组成
    
              时间戳 32bit
              服务器类型号 4bit [允许16种不同类型的服务器]
              服务器编号 12bit  [同一类型服务器允许4096台]
              递增序号 16bit   [该位数决定了每秒允许65536个不同的guid]
            */
            private static ulong c_mark_time_stamp = 0xffffffff00000000;/*时间戳掩码*/
            private static ulong c_mark_server_type = 0x00000000f0000000;/*服务器类型掩码*/
            private static ulong c_mark_server_id = 0x000000000fff0000;/*服务器编号掩码*/
            private static ulong c_mark_base = 0x000000000000ffff;/*本地ID编号掩码*/
            private static uint c_baseId = 0;/*本地ID*/
            private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    
            //生成唯一ID
            public static ulong NewGuid(ServerType server, uint id)
            {
                uint serverType = (uint)server;
                ulong timeStamp = (ulong)(DateTime.UtcNow - Jan1st1970).TotalSeconds;
                ulong newId = ((timeStamp << 32) & c_mark_time_stamp) | ((serverType << 28) & c_mark_server_type) | ((id << 16) & c_mark_server_id) | (c_baseId & c_mark_base);
    
                c_baseId++;
    
                return newId;
            }
            //根据唯一ID获取所在服务器类型与服务器编号
            public static void GetServer(ulong guid, out ServerType type, out uint id)
            {
                type = (ServerType)((guid & c_mark_server_type) >> 28);
                id = (uint)((guid & c_mark_server_id) >> 16);
            }
        }



    C++版本:

    const u_int64_t c_mark_time_stamp = 0xffffffff00000000;/*时间戳掩码*/
    const u_int64_t c_mark_district = 0x00000000fff00000;/*服务器区号掩码*/
    const u_int64_t c_mark_plat = 0x00000000000ff000;/*服务器里的平台号掩码*/
    const u_int64_t c_mark_base = 0x0000000000000fff;/*本地ID编号掩码*/
    
    
    u_int64_t gen_new_guid()
    {
        static u_int32_t baseId = 0;
        baseId++;
        u_int64_t timeStamp = (u_int64_t)time(NULL);
        u_int32_t districtNum = 1;/*这个服务器区号可以根据实际情况设置或者获取*/
        u_int32_t platNum = 1;/*这个平台号可以根据实际情况设置或者获取*/
        u_int64_t newId = ((timeStamp << 32)&c_mark_time_stamp) | ((districtNum << 20) & c_mark_district) | ((platNum << 12) & c_mark_plat) | (baseId & c_mark_base);
    }
  • 相关阅读:
    python requests模块
    python 模拟豆瓣登录(豆瓣6.0)
    python 抓取糗事百科糗图
    python bz2模块
    the python challenge闯关记录(9-16)
    python之PIL库(Image模块)
    python之zipfile
    python之pickle模块
    the python challenge闯关记录(0-8)
    KVO简介
  • 原文地址:https://www.cnblogs.com/legendstudio/p/4908500.html
Copyright © 2011-2022 走看看