zoukankan      html  css  js  c++  java
  • 高性能开发(第一篇哈希的运用)

    哈希的最底层的结构我就不说了。大家只需要明白哈希表是无序的。其查找和删除复杂度是O(1)的就行了。与哈希相关的C#中的常用的结构有HashSet<T>  Dictionary<key,value>

    1,  处理批量商品合并的问题。在商品助理项目中需要处理不同账户下的商品合并问题。

    那商品的合并操作有些什么呢?

    (1),两个不同类型店铺的同分类,同规格,同规格值下的商品货币,同商品下的货品合并。数据量,商品数量大概10,000个,货品大概100,000个。分类大概100个。规格大概50个,规格值大概200个。

    看起来数据量不大。实际上如果按照常规的处理合并方式会怎样呢?

    实际上如果不用到哈希处理这个规模的数据处理计算量是非常大的。首先两个店铺的分类id,商品id,规格id,规格值id,都不可能是一样的。而他们实际上是存在一个其他的对应关系。比如。两个店铺的分类名称相同我们就视为一个分类。商品的bn号相同视为同一个商品。货品编号相同视为同一种货品。然而这些字段都不是主键。在数据库中都加上索引可以提高一部分的查找性能。但是会大大降低数据库的添加和删除的性能。

    首先要遍历

    A店铺商品表 这一层:商品表的一级复杂度O(n) 也就是10,000。

    第二层。遍历B店铺的商品表,相同bn号的商品合并。又是10,000。而且要合并货品,平均每件商品对应10件货品。那也就是10*10.那么现在的处理数据的复杂度已经是10,000*10,000*10*10    一百亿了。别急还没有结束呢。

    第三层。要去查B店铺的分类,因为没有索引需要根据分类名称去B店铺的分类表一个个查。需要全表搜索分类的又是O(n) 分类100个 现在已经10,000亿的复杂度了。现在还没有处理规格和规格值的对应关系。当然规格和规格值仍然是和分类同级的。属于第三层这样怎么算也是万亿级的计算量。

    怎么说都是不能接受的。

    好吧现在我给出利用哈希的的解决方案。

     

    商品表 :商品id,商品bn号,其他字段。货品表:货品id,商品id,货品barcode,其他字段

    分类表:分类id,分类名称,其他字段。规格表:规格id ,规格名称,其他字段。

    规格值表:规格值id,规格id,规格值。

     

    首先遍历各个表。

    将关联关系作入字典。

    //便于定位对应bn号的商品和对应bn下不同shop_id(店铺id)号的的商品

    Dictionary<string, Dictionary<string, sys_goods>> goodsListdic = new Dictionary<string, Dictionary<string, sys_goods>>();

     

    /// <summary>

            /// 获取商品二级存储<bn,<bn+shop_id,sys_goods>>便于定位对应bn号的商品和对应bn下不同shop_id号的的商品

    /// </summary>

    /// <returns></returns>

            public Dictionary<string, Dictionary<string, sys_goods>> GetgoodsListDic()

            {

                try

                {

                    GoodsInfoService goodsService = new GoodsInfoService();

                    List<sys_goods> goodsList = goodsService.GetAll().ToList();

                    //goodsListdic二级存储<bn,<bn+shop_id,sys_goods>>便于定位对应bn号的商品和对应bn下不同shop_id号的的商品

                    Dictionary<string, Dictionary<string, sys_goods>> goodsListdic = new Dictionary<string, Dictionary<string, sys_goods>>();

                    foreach (var c in goodsList)

                    {

                        if (c.bn != null)

                            if (!goodsListdic.ContainsKey(c.bn))

                            {

                                Dictionary<string, sys_goods> newdic = new Dictionary<string, sys_goods>();

                                newdic.Add(c.bn + c.shop_id, c);

                                goodsListdic.Add(c.bn, newdic);

                            }

                            else

                            {

                                if (!goodsListdic[c.bn].ContainsKey(c.bn + c.shop_id))

                                    goodsListdic[c.bn].Add(c.bn + c.shop_id, c);

                            }

                    }

                    return goodsListdic;

                }

                catch (Exception e)

                {

                    return new Dictionary<string, Dictionary<string, sys_goods>>();

                }

            }

    很显然以上的代码的复杂度无非就是遍历了下商品表。是O(n)的。但是这个操纵就使得旧方案的第二层的复杂度大大降低因为现在可以从字典中根据bn号查找商品了。现在第二层的复杂度是O(1)的。好了现在的全部处理复杂度已经降低到1亿级别了。

    以此类推,将分类作入字典我们需要根据分类名称查找,那么做一个分类名称为健的分类字典<分类名称,分类> 就可以使得通过分类名称查找分类的复杂度变为O(1)同样,将规格和规格值,作入字典。这样合并两店铺的商品的操做复杂度就是100,000级别了。看到这里很清楚了吧。操纵效率提高了近一千万倍。

     

    我想近期换一份工作    我的qq:1424394610.

  • 相关阅读:
    datanode报错Problem connecting to server
    使用命令查看hdfs的状态
    Access denied for user root. Superuser privilege is requ
    ElasticSearch默认的分页参数 size
    SparkStreaming Kafka 维护offset
    【容错篇】Spark Streaming的还原药水——Checkpoint
    251 Android 线性与相对布局简介
    250 Android Studio使用指南 总结
    249 如何解决项目导入产生的中文乱码问题
    248 gradle更新问题
  • 原文地址:https://www.cnblogs.com/hujiapeng2012/p/3025023.html
Copyright © 2011-2022 走看看