范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

巧用二进制,让性能提升100倍,让存储空间减少100倍

  假设有一个需求是这样的:在200亿个随机整数中找出某个数是否存在其中?要求效率高,而且要节省内存。
  我们知道,在Java中,int占4字节,1字节=8 byte,1 byte = 8 bit(位)
  如果用int存储,那就是200亿个int,因而占用的空间约为
  (20000000000*4/1024/1024/1024)≈74.5G。
  内存消耗很大,一般的家用电脑是满足不了需求的,所以将数据存储在内存中存储是不合适的。
  如果按位存储就不一样了,200亿个数就是200亿位,占用空间约为
  (2000000000/8/1024/1024/1024)≈2.33G,节省了30倍的空间。
  实际上这就是Bitmap的思想。Bitmap的基本思想是用一个bit位来标记某个元素对应的Value,而Key即是该元素本身。采用bit存储数据,可以大大节省存储空间。
  Bitmap是什么?如何在bitmap中表示一个数呢?
  我们知道计算机底层存储的都是二进制数据,二进制数只有0和1。bitmap每一位的值也只能是0或1,0表示不存在,1表示存在。
  这样我们可以很容易表示{1,2,4,6}这几个数:
  计算机内存分配的最小单位是字节,也就是8位,那如果要表示{12,13,15}怎么办呢?
  当然是在另一个8位上表示:
  这样的话,好像变成一个二维数组了
  1个int占32位,那么我们只需要申请一个int数组长度为 int tmp[1+N/32] 即可存储,其中N表示要存储的这些数中的最大值,于是:
  tmp[0]:可以表示0~31
  tmp[1]:可以表示32~63
  tmp[2]:可以表示64~95
  …
  于是,对于任意整数M,M/32可以得到下标,M%32就可以得到它在此下标的哪个位置。
  那么,怎么把一个数放进Bitmap呢?比如想把5这个数字放进去
  插入一个数
  首先,5/32=0,5%32=5,也是说它应该在b[0]的第5个位置。我们可以把1向左移动5位,然后和b[0]按位或即可。
  二进制就是:
  这就相当于 86 | 32 = 118,即 86 | (1<<5) = 118,也就是 b[0] = b
  [0] | (1<<5)。也就是说,要想插入一个数,将1左移相应的位数,然后与原数进行按位或操作即可。
  删除一个数
  还是上面的例子,假设删除数字6,该怎么做呢?
  只需将该数所在的位置为0即可。即1左移6位,就到达6这个数字所代表的位,然后按位取反,最后与原数按位与,这样就把该位置为0了
  公式如下:
  b[0] = b[0] & (~(1<<6))
  b[0] = b[0] & (~(1<<(i%8)))
  查找一个数
  前面已经提到,1表示存在,0表示不存在。通过把该位置为1或者0来达到添加和清除的效果,那么判断一个数存不存在就是判断该数所在的位是0还是1。比如,我们想知道6在不在,那么只需要判断 b[0] & (1<<6), 如果这个值是0,则不存在,如果是1,就表示存在。
  BitMap在统计系统里边能做什么?
  例子 1:针对独立用户的统计。比如想知道某个应用,每天有多少个独立用户使用了该应用?可以根据该应用的用户访问日志,每天生成一个BitMap;每个用户对应BitMap里的一个位置,如果当天访问了,该位置就置为1,否则为0。这样要知道当天这个应用的总独立用户数,只需要看看那天的BitMap里边有多少个1。
  对于10M(1000万)用户的应用,每天需要的BitMap大小为10M/8=1.25MB,即只需要1.25兆字节。在采用一些压缩技术的基础上,可以进一步缩减需要的存储量,一般情况下可能只需要大约100-200KB的存储即可。
  例子2:用户回访的统计。比如想知道某个应用,昨天使用过的用户中,有多少今天也使用了?可以在例子1(每天保存一个独立活跃用户的BitMap)的基础上,将昨天的BitMap和今天的BitMap进行AND操作,然后数一下生成的BitMap里有多少个1即可。
  怎么将用户映射到BitMap里边的某个位置?
  使用BitMap的时候,都需要将原始数据(比如用户)映射到BitMap里的位置;这种映射一般可以采用外部数据(比如在数据库里保存用户到BitMap位置的映射),或者采用固定的规则(比如计算用户名的hash code)。
  采用第一种方法时,通常是在数据库里边给用户分配一个数值型的用户ID,而用户ID的生成规则采用自增量的方式来产生;这样比如有100个用户,则其用户ID为1,2,3,…,98,99,100;用户ID为1的用户映射到BitMap里的第1个位置,用户ID为2的用户映射到BitMap里的第2个位置…(问题:如果自增量的初始值不是0,而是比如10000,会产生什么影响?)
  采用自增量的另外一个好处是,系统用户数少的时候,BitMap需要的位数也少;当用户量增长时,BitMap的位数跟着增长即可;而且如果记住每天的总用户数,BitMap里边还可以直接表明每天的新增用户是哪些(注意:此处对于我们的分析系统不一定适用)
  采用第二种方法时,最常使用的规则是计算用户的hash(比如Object.hashCode,或者MD5);但由于hash生成的数字分布很宽(比如java里边Object的hashCode会返回一个int,所以其分布是-231 – 231-1),但需要的BitMap的位数往往不用那么大,这样就需要再做一个hashcode到BitMap里位置的映射(一般是取余数),这就要求必须预先知道BitMap的大小,且这个大小一般要求保持不变。
  比如要求将用户映射到一个1024位的BitMap:用户A的hashcode是101,101除1024取余数是101,所以用户A就对应BitMap的第101位;而用户B的hashcode是1234567,1234567除1024取余数是647,用户B就对应BitMap的第647位。
  第二种方法由于采用固定的规则来计算映射,而不需要去做外部数据查询,因此映射这部分的开销会较第一种方法低很多。但第二种方法也有两个缺点,其一是如果预期总用户量会增长到1百万,即使目前系统只有1000个用户,也需要一个1百万位的BitMap,这样会造成很大的存储和计算资源的浪费;其二是hashcode有冲突的问题(即有可能用户C和用户D计算出来的hashcode是一样的);
  而hashcode到BitMap里位置的映射也会造成更多的冲突(比如用户E和用户F的hashcode分别是12345678和12377422,但除1024取余后都是334)。这些冲突的存在,导致了数据可信度的下降,比如BitMap里的第334位为0,则可以知道用户E和F都不在;但如果第334位为1,则并不知道用户E或者用户F是不是在。
  采用第二种方法的BitMap,有一个更广为人知的名字,即Bloom Filter (http://en.wikipedia.org/wiki/Bloom_filter)。Bloom Filter经常用于文本分析中来记录某个词是否已经出现;或者垃圾邮件过滤中来检查邮件地址是否在已知的垃圾邮件地址列表里。
  Bloom filter(布隆过滤器)
  来了解一下Bloom filter, Bloom filter是一个数据结构,它可以用来判断某个元素是否在集合内,具有运行快速,内存占用小的特点。插入和查询效率都很高。Bloom Filter 是一个基于概率的数据结构:它只能确定一个元素不在集合内,不能确定一定在集合内。
  Bloom filter 的基础数据结构是比特向量,可理解为数组。
  主要应用于大规模数据下不需要精确过滤的场景,如检查垃圾邮件地址,爬虫URL地址去重,解决缓存穿透问题等
  如果想判断一个元素是否在集合里,一般想到的是将集合中所有元素保存起来,然后通过比较确定。链表、树、散列表等数据结构都是这种思路,但是随着集合中元素的增加,需要的存储空间越来越大;同时检索速度也越来越慢,检索时间复杂度分别是O(n)、O(log n)、O(1)。
  布隆过滤器的原理是,当一个元素被加入集合时,通过 K 个散列(hash)函数将这个元素映射成一个位数组(Bit array)中的 K 个点,把它们置为 1 。检索时,只要看看这些点是不是都是1就知道元素是否在集合中;如果这些点有任何一个 0,则被检元素一定不在;如果都是1,则被检元素很可能在。之所以说"可能",是因为可能有hash冲突的问题。
  BloomFilter 流程:
  首先需要 k 个 hash 函数,每个函数可以把 key 散列成为 1 个整数;
  初始化时,需要一个长度为 n 比特的数组,每个比特位初始化为 0;
  某个 key 加入集合时,用 k 个 hash 函数计算出 k 个散列值,并把数组中所有对应的比特位置为 1;
  判断某个 key 是否在集合时,用 k 个 hash 函数计算出 k 个散列值,并查询数组中对应的比特位,如果所有的比特位都是1,则key很可能在集合中。如果其中任意一个比特位为0,则确定key不在集合中。
  由此可见,如果我们能灵活运行二进制,确实能给系统带来不少好处。所有的程序和指令在执行前都会被转化成0和1,所以我们用二进制的0和1直接和计算机交互效率是最高的,而且能大幅节省空间。所以大家一定要关心计算机基础啊,基础扎实了,我们的技术能力才能上新的台阶。
  号主简介:冯涛,曾任职于阿里巴巴,每日优鲜等互联网公司,任技术总监,15年电商互联网经历。

7岁女孩报14个辅导班,储殷10岁以下娃报班基本无用,关注3件事文凝妈青岛一个7岁女孩,现在上二年级,每周居然要上14个辅导班,看到这个数量也是震惊了。再看她的时间安排,也让人感到费解。周二下午1点半学国画下午3点学硬笔书法晚上6点英语外教课。时间的礼物是一分一秒的陪伴,累积成我们不可替代的情感世界上唯一有价值的东西就是时间,一秒钟就是一秒钟,没有讨价还价的余地。这是一个关于时间和选择的故事时间的礼物灵感来源于作者雷德里克巴克曼自身的生活体验。它讲述了一名把生命中的每分每人生步履不停,愿现在的你我,一切都还来得及横山良多年过半百的自由画家横山良多,一名自由画家,在我不惑之年的初春,我成为了一名丈夫也成了一位小学五年级孩子的爸爸。在四十而立的年纪,我把人生比作一场马拉松,还未到终点,还有许多穷查理宝典为什么巴菲特都说这本书穷人必读?如果你是巴菲特,格雷厄姆,价值投资的爱好者,那么你应该对查理芒格不陌生。查理芒格是巴菲特50多年的朋友和合伙人好搭档,也是伯克希尔哈撒韦的副主席。与巴菲特一样,查理也是生在奥马哈。孟小冬传与梅兰芳情深,与杜月笙缘浅文早安读书如果你对民国那个时代感兴趣,那你一定知道赫赫有名的梅兰芳和权势显赫的杜月笙。而这两位家喻户晓耳熟能详的两位名人,都曾经爱过孟小冬。01出身梨园1907年的冬天,雪花漫天飞杨绛我的人生,为何与众不同?杨绛先生对我来说,是非常敬仰的人。读书,杨绛先生说要用生活所感去读书,用读书所得去生活。教育,杨绛先生说好的教育首先是启发人的学习兴趣,要让学生在不知不觉中受教育,让他们潜移默化。孩子上一年级前,家长要做好幼小衔接,以便孩子轻松适应小学生活文凝妈悟语中小学的孩子们纷纷放了暑假,也意味着新学期不远了,再有不到两个月的时间,又会有一批小学生进入一年级,家长们不免焦虑起来。有网友就来提问了小学暑假期间,到底应不应该给孩子报于凤至传为何少帅张学良,直呼一生只辜负她?文早安读书于凤至和张学良的姻缘,要从父辈们说起。初次相识是因为张学良的父亲张作霖被调去辽源州,而于文斗邀请了张作霖到府上喝茶,聊天甚欢。于凤至的父亲于文斗有一次在张作霖在剿匪图中被如果你是家长,请一定要带孩子去看中国医生文凝妈悟语暑假来了,神兽们纷纷开启了整日整夜的闹腾模式,这让很多家长头痛不已,可那又能怎么办呢?自己生的崽,跪着也得养着啊。于是她们纷纷使出浑身解数,给孩子制定了各种各样的计划,关为什么不呼救不逃跑不反抗?心理分析性侵当事者的主体感受人的内心,既求生,也求死。我们既追逐光明,也追逐黑暗。我们既渴望爱,有时候却又近乎自毁地浪掷手中的爱,人的心中好像只有一片荒芜的夜地,留给那个幽暗又寂寞的自我。前言随着自媒体时代的心理学爱的浓,不如爱得长久,女人要学会如何持续吸引男人人在福中不知福,直到有一天苦了,才对比出以前的甜。所以甜中总有苦,福中总有祸的人,最能感受幸福。所以,淡淡的君子之交最能长久,若即若离的爱情最堪回味。前言在感情中每个女性都渴望得到
禁止公办高中复读,这背后隐藏着一个巨大信号高考放榜的前几天,重庆的一纸通知,让部分山城学子辗转难眠。全市普通高中学校不得举办复读班,不得招收复读插班生。这意味着,这一届考生如果想要复读,只能转战私立学校和培训机构,费用更贵文科生和理科生,毕业后谁的发展潜力更大?过来人现身说法很真实进入高中后学生就要面临文理科的选择,而这选择直接影响高考成绩。在高考这场决定人生的考试中,是分文理科的,在这种情况下,学生势必要选择一个更擅长的科,这样才能尽可能得高分。而一旦选完2021公费师范生招生遇冷,河南补录418人,难道铁饭碗不香了?随着大学生就业形势严峻,越来越多学生开始向往铁饭碗工作。近年来,教师,公务员,国企等岗位已经成为大学生就业的首要目标,为了实现目的,在大一期间就开始努力,尽可能为自己增加优势。不仅2021幼师入职有调整,专科生无法成为幼师?没你想的那么简单幼儿园是启蒙,更是校园教育的基础。当学生成长到2岁时,父母就要开始考虑将学生送到幼儿园的事情了,毕竟目前大多数孩子都是3岁以后就开始上学了。幼儿园是学生第一次离开父母进入集体生活,考不上本科是智商有问题,HR口出狂言引众怒,但也反映了现实在如今这个大学生逐年递增的时代中,学历越发重要。高考是大多数人人生中非常重要的考试之一,因为高考后的成绩决定学生能上哪个等级的大学。在当今社会中,关于学历一直都是存在鄙视链的,982021第二次征兵正在进行,身高标准有新变化,同时专科生更有优势在国家和军人的保护下,人们才能有如今这种幸福平稳的好生活。在国人心中,军人的地位是非常高的,即使是年纪很小的学生见到军人后也会不自觉地肃然起敬,不敢造次。并且由于种种因素,很多人心为何女生上高中后,成绩会出现断崖式下降?老师说出其中缘由中考是教育第一次分层,经过中考后,学生将根据成绩被分到不同地方,接受不同教育。关于中考,近些年来总有家长呼吁取消,认为学生年纪太小,根本不懂得学习重要性,那时就经历分层,对开窍晚的北大校花博士火了,长相撞脸孟子义,评论区却不堪入目文章字数大约1174字阅读时长约3分钟都说人无完人,一个人不可能是十全十美,肯定多少还是存在着一丝丝缺陷。但是这个话也并不绝对,在诺大的世界当中,总是会存在被造物主所偏爱的人群。普农谚秋败茄子似毒药,秋败丝瓜胜良药,什么意思?茄子不能吃?明天就是大暑节气了,气温蹭蹭蹭地往上涨,正如农俗所言小暑大暑,上蒸下煮。不过,凡是物极必反,大暑高温过后,就相对凉快了,因为距离立秋就不是太远了。每个季节,都有应季蔬果,比如秋不食国际女童日拒绝重男轻女,倾听女童声音,开创平等未来在世界范围内,特别是在发展中国家,女童往往面临更多的性别歧视和不平等待遇。在世界许多地区,女童仍承受着战争的残酷与饥饿的折磨,甚至被性侵被拐卖,饱尝暴力的戕害和失学的痛苦即便是现在宝宝过早吃盐危害大,4个制作妙招,让宝宝爱上没味道的辅食世界卫生组织提倡纯母乳喂养至少6个月,随着宝宝一天天长大,母乳已不能全面满足婴儿的营养需求,这时就需要给宝宝添加辅食了。中国居民膳食指南(2016)中指出,辅食应保持原味,不加盐糖