精华内容
下载资源
问答
  •   最近开始一些大工程量的python代码,作为深度学习小白,每次看着那么多份文件、遇到几千行代码就很头疼,无从下手。而且经常会遇到了后边忘前面、不下去等问题。   搜了一些博客和知乎,看到了大神们...

      最近开始看一些大工程量的python代码,作为深度学习小白,每次看着那么多份文件、遇到几千行代码就很头疼,无从下手。而且经常会遇到看了后边忘前面、看不下去等问题。
      搜了一些博客和知乎,看到了大神们提出的阅读代码的方法,就想着整理一下,可帮助自己梳理代码逻辑和进阶写代码。最近也有在实践,感觉比硬着头皮看要好多了,希望以后能更加熟练!
      以下只涉及阅读学习的一些方法。当然,想要掌握得更好,光阅读是不够的,一定要动手写、训练模型!!!调参、调bug的过程也是吸收的过程。(就像高中做题一样)


      首先,想要解决一个问题,最先要分析出现问题的原因

    影响阅读速度可能的原因

    • 对整体的思路没有概念
    • 不熟悉常用的类库、函数,包括方法调用不熟悉
    • 不熟悉python常用的编程技巧
    • 不理解里面的一些算法
    • 中途停顿时间太长,接过来后没有形成一个系统的思路。

      接下来,就是具体的一些方法和技巧。

    阅读方法

    1.整体到局部

    • 把握整体。有个大体的框架在脑海中,此时根据里面的文件名和文件夹,从入口文件大段大段看就可以,知道这段或者这个文件的作用就可以。
    • 找到入口后,可以顺着入口来看每个函数的作用和意思;或者可以先看看核心模型部分的算法,标注每个类、函数的作用。

    2.熟悉类库、编程模块

    • 首先,影响代码阅读的最核心的问题是对类库不熟悉会带来的问题:引起阅读时左右查资料,精力太分散,一句一句读,经常需要上网查语法,没有办法把精力放在代码的整体结构上,即使是每行代码都看明白了还是不知道整个程序的逻辑,同时耗费精力比较大,很快就累了,效率很低。
    • 整理学习。把不熟悉的类库全部整理出来,到官网查用法,一次性过一遍。注意,此时不用全部看,只需要查调用到的地方什么意思,弄明白调用的意思即可。
    • 略读,逻辑很重要。熟悉了常用库和编程技巧之后读代码的时候很多功能自己都实现过类似的,或者之前见过,扫一眼就看明白了,很多函数扫一眼就知道什么功能,思路不会被不懂得语法或者编程技巧打断,一直停留在程序的逻辑上,这样看代码就轻松多了,而且很快。
    • 总结建立自己的代码库。代码看的多了就会发现有些语句是非常常用的,而且已经形成套路了,在阅读的过程中可以将这些代码段总结下来,便于以后使用。

    3.静心看算法,及时看论文

    • 遇到不熟悉的算法一定要提醒自己静下心来。
    • 如果有注释可以根据注释来理解。
    • 如果没有,一方面可以先跳过,继续了解整体,然后再细分了解这个算法;另一方面及时返回论文,去看模型的思路或实验中的一些细节等,论文相当于部分代码注释,而且还能帮助加深模型的理解。

    4.连续性

    • 趁热打铁。最好不要今天看一点点,隔了非常长的时间再看其他部分。
    • 如果实在看不完就先把一个较完整的模块看完,有必要一定要做记录,方便明天再看。

    5.好记性不如烂笔头-阅读代码的两种模式

    这个部分参考了一位大神的回答:
    https://www.zhihu.com/question/21186887/answer/18195570

    • top-down 模式:就是先设定一个 use case,比如说打开一个文件。然后静态跟着代码看,或者用 debugger 跟着看。每次出现函数调用的时候,把函数的执行层次纪录下来。把重要的「实际参数」一直标下来,这样阅读深层次代码不用再回头查形式参数到底指什么。大致如下:
    f1( para1, para2,)
       f2( para1, para2,)
           f4( para1, para2,)
       f3( para1, para2,)
    
    • bottom-up 模式:top-down 模式进行到一定层次,往往会发现虽然图画了出来,但还是无法了解程序再干什么。这时需要转入 bottom-up 模式,一直深入到最底层,给能了解作用的底层函数一个一个的写文档。当然这时的文档是完全底层的观点。

    一些心得体会

    • 将代码当作阅读理解来读!
      文章尚且是有逻辑的,代码也是。我们读文章的时候最重要的不是记住里面优美的句子,而是要能够理解作者所说(也就是文章的内涵、中心思想)。代码也是一样,将它看作优美的文章,想象着自己在探索一个真理、在读一个有趣的故事,这样看起来就不会太枯燥无味了。
    • 带着目标去读,往往效率高而且不容易困!
      如果只是消遣,那往往就是读完文章后总结一些内容就作罢。但是要想学习到文章中更深刻的内容,就需要另一种方式。给自己提问题,比如:这段代码什么作用、参数怎么调用的、代码整体逻辑是什么样的等等,这样在读代码的过程中就会有针对性地去学习,也比较容易能记住。

    最后,最重要的,一定是动手去练、去写!

    • 可以对每一小步、每一个小语句或每一个代码块进行输出,看结果,来熟悉语句
    • 训练整体的模型
    展开全文
  • 如何写出漂亮的代码

    2021-01-20 03:45:17
     如何自己的代码变得可读性强呢? 从简单也是难的做起,有意义的名称 + 减少方法的长度。  我过很多遗留系统的代码,里面大都充斥着大方法,多层缩进。如果不是逼不得已,个人是不愿意去读的。像读文章...
  • 前一段时间了一阵子ORM,感觉有单表都还简单,最头痛就是如何控制多表关联那些没必要SQL语句,可能自己还没什么仔细看的缘故吧。 目前拥有框架是基于DataSet,支持多表关联,已经可以彻底摆脱Insert/...
           前一段时间看了一阵子的ORM,感觉有单表的都还简单,最头痛的就是如何控制多表关联那些没必要的SQL语句,可能自己还没什么仔细看的缘故吧。
          目前拥有的框架是基于DataSet的,支持多表关联,已经可以彻底的摆脱Insert/Update/Delete语句了,后来又增加了UpdateObject 和 DeleteObject 来减少基于DataSet而能导致的Sql语句执行的次数烦多的缘故。现在为了减少程序员编码的痛苦,同时,又能得到编译时类型控制,往Data层增加Entity,一般是贫血Object,纯粹拥有属性,没有方法的。
            原来是一个DataSet 囊括了构建DataTable的功能。现在增加BaseEntity ,BaseDataTable类。BaseEntity 有一个属性RowIndex ,用来保存对应的行号,如果是新增RowIndex=-1 否则对应行号。BaseDataTable 有3个虚方法:1。获取实体类 public virtual BaseEntity GetEntity(int rowIndex)  2。创建一个实体类 public virtual BaseEntity CreateEntity() 3。 把实体值转入DataRow中 public virtual bool SetEntity(BaseEntity entity)  
           这样,我们就可以使用代码生成器来构建我们需要的对象。
           比如
                 OrdersDataSet 需要拥有 OrdersTable ItemsTable DeliveriesTable  OrdersEntity ItemsEntity DeliveriesEntity
                 OrdersDataSet 只需要拥有3个Public 的 OrdersTable ItemsTable DeliveriesTable
                 OrdersTable 需要Override那三个方法,然后 使用OrdersEntity
                 ItemsTable以此类推.....
          
            1.获取实体以及修改保存
                       OrdersEntity entity=ordersDataSet.OrdersTable.GetEntity(0) as OrdersEntity ;
                       Console.WirteLine("Order ID is"+entity.OrderID);
                       entity.Quantity=20;
                      ordersDataSet.OrdersTable.SetEntity(entity);
            2.新增一个实体,并设置值以及保存入表格
                       OrdersEntity newEntity=ordersDataSet.OrdersTable.CreateEntity() as OrdersEntity;
                       newEntity.OrderID="xxxxx";
                       ordersDataSet.OrdersTable.SetEntity(newEntity);
            当然了,如上的代码,如果移植到.Net2.0就可以充分的利用泛型,但是还有几个网站在1.1下, 不敢一下子更换。.........
            通过这种封装,我们可以减少原本基于DataRow的赋值和获取值的麻烦,而且类型也是编译时安全的。
    当然了,我知道这不可能时ORM  :)因为我是使用硬编码,只是通过代码生成器可以减少编写这么多麻烦的重复的代码。事实也证明了这种方式的开发的快速性,不过,不够OO,因为是基于Table的。相对来说,对于大企业的大系统不适合,中小企业还可以吧,个人觉得:)
             呵呵,虽然自己的框架不是优秀的,但是,用的习惯了,觉得还是很快的,虽然没有拥有那么多令人骄傲的特色,没有那么OO,但是也足够我自己用了~_~ ! 自己是多么的不求上进,但是依然要写很多Select语句来获取复杂的查询数据。

     sample code 如下:

    None.gifusing System;
    None.gif
    using FishSky.Data.Base;
    None.gif
    None.gif
    namespace FishSky.Data.Chateau
    ExpandedBlockStart.gifContractedBlock.gif
    dot.gif{
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    /**////<summary>
    InBlock.gif    
    /// SendOutEntity实体类
    ExpandedSubBlockEnd.gif    
    ///</summary>

    InBlock.gif    public class SendOutEntity : BaseEntity
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    dot.gif{
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    构造函数#region 构造函数
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        // 构造函数
    ExpandedSubBlockStart.gifContractedSubBlock.gif
            /**////</summary>
    InBlock.gif        public SendOutEntity()
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    出库单#region 出库单
    InBlock.gif
    InBlock.gif        
    private String mSendOutNo;
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        // 出库单
    ExpandedSubBlockStart.gifContractedSubBlock.gif
            /**////</summary>
    InBlock.gif        public String SendOutNo
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    get dot.gifreturn mSendOutNo; }
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    set dot.gif{ mSendOutNo = value; }
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    发票号#region 发票号
    InBlock.gif
    InBlock.gif        
    private String mInvoiceNo;
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        // 发票号
    ExpandedSubBlockStart.gifContractedSubBlock.gif
            /**////</summary>
    InBlock.gif        public String InvoiceNo
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    get dot.gifreturn mInvoiceNo; }
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    set dot.gif{ mInvoiceNo = value; }
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    总计#region 总计
    InBlock.gif
    InBlock.gif        
    private Decimal mAmount;
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        // 总计
    ExpandedSubBlockStart.gifContractedSubBlock.gif
            /**////</summary>
    InBlock.gif        public Decimal Amount
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    get dot.gifreturn mAmount; }
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    set dot.gif{ mAmount = value; }
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    操作员#region 操作员
    InBlock.gif
    InBlock.gif        
    private String mUserName;
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        // 操作员
    ExpandedSubBlockStart.gifContractedSubBlock.gif
            /**////</summary>
    InBlock.gif        public String UserName
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    get dot.gifreturn mUserName; }
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    set dot.gif{ mUserName = value; }
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    操作员中文名#region 操作员中文名
    InBlock.gif
    InBlock.gif        
    private String mChineseName;
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        // 操作员中文名
    ExpandedSubBlockStart.gifContractedSubBlock.gif
            /**////</summary>
    InBlock.gif        public String ChineseName
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    get dot.gifreturn mChineseName; }
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    set dot.gif{ mChineseName = value; }
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    客户代码#region 客户代码
    InBlock.gif
    InBlock.gif        
    private String mCustomerCode;
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        // 客户代码
    ExpandedSubBlockStart.gifContractedSubBlock.gif
            /**////</summary>
    InBlock.gif        public String CustomerCode
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    get dot.gifreturn mCustomerCode; }
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    set dot.gif{ mCustomerCode = value; }
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    客户中文名#region 客户中文名
    InBlock.gif
    InBlock.gif        
    private String mCustomerName;
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        // 客户中文名
    ExpandedSubBlockStart.gifContractedSubBlock.gif
            /**////</summary>
    InBlock.gif        public String CustomerName
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    get dot.gifreturn mCustomerName; }
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    set dot.gif{ mCustomerName = value; }
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    备注#region 备注
    InBlock.gif
    InBlock.gif        
    private String mRemark;
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        // 备注
    ExpandedSubBlockStart.gifContractedSubBlock.gif
            /**////</summary>
    InBlock.gif        public String Remark
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    get dot.gifreturn mRemark; }
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    set dot.gif{ mRemark = value; }
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    货款付讫#region 货款付讫
    InBlock.gif
    InBlock.gif        
    private String mIsPaid;
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        // 货款付讫
    ExpandedSubBlockStart.gifContractedSubBlock.gif
            /**////</summary>
    InBlock.gif        public String IsPaid
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    get dot.gifreturn mIsPaid; }
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    set dot.gif{ mIsPaid = value; }
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    出售日期#region 出售日期
    InBlock.gif
    InBlock.gif        
    private DateTime mSendOutDate;
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        // 出售日期
    ExpandedSubBlockStart.gifContractedSubBlock.gif
            /**////</summary>
    InBlock.gif        public DateTime SendOutDate
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    get dot.gifreturn mSendOutDate; }
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    set dot.gif{ mSendOutDate = value; }
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    ExpandedSubBlockEnd.gif    }

    ExpandedBlockEnd.gif}

     

     

    None.gifusing System;
    None.gif
    using System.Data;
    None.gif
    using FishSky.Data.Base;
    None.gif
    None.gif
    namespace FishSky.Data.Chateau
    ExpandedBlockStart.gifContractedBlock.gif
    dot.gif{
    InBlock.gif    
    public class SendOutDataTable : BaseDataTable
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    dot.gif{
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    表格常量#region 表格常量
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    /// 定义对象数据集表名:SendOut
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public const String TBL_SendOut = "SendOut";
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    ///出库单
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public const String SendOutNo_SendOut = "SendOutNo";
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    ///发票号
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public const String InvoiceNo_SendOut = "InvoiceNo";
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    ///总计
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public const String Amount_SendOut = "Amount";
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    ///操作员
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public const String UserName_SendOut = "UserName";
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    ///操作员中文名
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public const String ChineseName_SendOut = "ChineseName";
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    ///客户代码
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public const String CustomerCode_SendOut = "CustomerCode";
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    ///客户中文名
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public const String CustomerName_SendOut = "CustomerName";
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    ///备注
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public const String Remark_SendOut = "Remark";
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    ///货款付讫
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public const String IsPaid_SendOut = "IsPaid";
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    ///出售日期
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public const String SendOutDate_SendOut = "SendOutDate";
    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion
     
    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    构造函数#region 构造函数
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        
    /// 构造函数
    ExpandedSubBlockEnd.gif        
    ///</summary>

    InBlock.gif        public SendOutDataTable()
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    InBlock.gif            
    this.TableName = TBL_SendOut;
    InBlock.gif            DataColumnCollection columns 
    = this.Columns;
    InBlock.gif            DataColumn column;
    InBlock.gif            column 
    = new DataColumn(SendOutNo_SendOut, typeof (String));
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isPrimaryKeyColumn, 
    true);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isSecondaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isValidColumn, 
    true);
    InBlock.gif            column.MaxLength 
    = 50;
    InBlock.gif            column.DefaultValue 
    = " ";
    InBlock.gif            columns.Add(column);
    InBlock.gif
    InBlock.gif            column 
    = new DataColumn(InvoiceNo_SendOut, typeof (String));
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isPrimaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isSecondaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isValidColumn, 
    true);
    InBlock.gif            column.MaxLength 
    = 50;
    InBlock.gif            column.DefaultValue 
    = " ";
    InBlock.gif            columns.Add(column);
    InBlock.gif
    InBlock.gif            column 
    = new DataColumn(Amount_SendOut, typeof (Decimal));
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isPrimaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isSecondaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isValidColumn, 
    true);
    InBlock.gif            column.DefaultValue 
    = 0;
    InBlock.gif            columns.Add(column);
    InBlock.gif
    InBlock.gif            column 
    = new DataColumn(UserName_SendOut, typeof (String));
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isPrimaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isSecondaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isValidColumn, 
    true);
    InBlock.gif            column.MaxLength 
    = 20;
    InBlock.gif            column.DefaultValue 
    = " ";
    InBlock.gif            columns.Add(column);
    InBlock.gif
    InBlock.gif            column 
    = new DataColumn(ChineseName_SendOut, typeof (String));
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isPrimaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isSecondaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isValidColumn, 
    true);
    InBlock.gif            column.MaxLength 
    = 50;
    InBlock.gif            column.DefaultValue 
    = " ";
    InBlock.gif            columns.Add(column);
    InBlock.gif
    InBlock.gif            column 
    = new DataColumn(CustomerCode_SendOut, typeof (String));
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isPrimaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isSecondaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isValidColumn, 
    true);
    InBlock.gif            column.MaxLength 
    = 20;
    InBlock.gif            column.DefaultValue 
    = " ";
    InBlock.gif            columns.Add(column);
    InBlock.gif
    InBlock.gif            column 
    = new DataColumn(CustomerName_SendOut, typeof (String));
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isPrimaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isSecondaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isValidColumn, 
    true);
    InBlock.gif            column.MaxLength 
    = 50;
    InBlock.gif            column.DefaultValue 
    = " ";
    InBlock.gif            columns.Add(column);
    InBlock.gif
    InBlock.gif            column 
    = new DataColumn(Remark_SendOut, typeof (String));
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isPrimaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isSecondaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isValidColumn, 
    true);
    InBlock.gif            column.MaxLength 
    = 100;
    InBlock.gif            column.DefaultValue 
    = " ";
    InBlock.gif            columns.Add(column);
    InBlock.gif
    InBlock.gif            column 
    = new DataColumn(IsPaid_SendOut, typeof (String));
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isPrimaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isSecondaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isValidColumn, 
    true);
    InBlock.gif            column.MaxLength 
    = 1;
    InBlock.gif            column.DefaultValue 
    = " ";
    InBlock.gif            columns.Add(column);
    InBlock.gif
    InBlock.gif            column 
    = new DataColumn(SendOutDate_SendOut, typeof (DateTime));
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isPrimaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isSecondaryKeyColumn, 
    false);
    InBlock.gif            column.ExtendedProperties.Add(BaseConst.isValidColumn, 
    true);
    InBlock.gif            column.DefaultValue 
    = DateTime.Now;
    InBlock.gif            columns.Add(column);
    InBlock.gif
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    创建实体#region 创建实体
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        
    /// 创建实体
    InBlock.gif        
    ///</summary>
    ExpandedSubBlockEnd.gif        
    ///<returns>实体</returns>

    InBlock.gif        public override BaseEntity CreateEntity()
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    InBlock.gif            
    return new SendOutEntity();
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    获取指定行号的实体#region 获取指定行号的实体
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        
    /// 获取指定行号的实体
    InBlock.gif        
    ///</summary>
    InBlock.gif        
    /// <param name="rowIndex">行号</param>
    ExpandedSubBlockEnd.gif        
    /// <returns>实体</returns>

    InBlock.gif        public override BaseEntity GetEntity(int rowIndex)
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    InBlock.gif            
    if (rowIndex >= 0 && rowIndex <= this.Rows.Count)
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    dot.gif{
    InBlock.gif                SendOutEntity entity 
    = new SendOutEntity();
    InBlock.gif                entity.RowIndex 
    = rowIndex;
    InBlock.gif                DataRow dr 
    = this.Rows[rowIndex];
    InBlock.gif                entity.SendOutNo 
    = dr[SendOutNo_SendOut].ToString();
    InBlock.gif                entity.InvoiceNo 
    = dr[InvoiceNo_SendOut].ToString();
    InBlock.gif                entity.Amount 
    = Convert.ToDecimal(dr[Amount_SendOut]);
    InBlock.gif                entity.UserName 
    = dr[UserName_SendOut].ToString();
    InBlock.gif                entity.ChineseName 
    = dr[ChineseName_SendOut].ToString();
    InBlock.gif                entity.CustomerCode 
    = dr[CustomerCode_SendOut].ToString();
    InBlock.gif                entity.CustomerName 
    = dr[CustomerName_SendOut].ToString();
    InBlock.gif                entity.Remark 
    = dr[Remark_SendOut].ToString();
    InBlock.gif                entity.IsPaid 
    = dr[IsPaid_SendOut].ToString();
    InBlock.gif                entity.SendOutDate 
    = Convert.ToDateTime(dr[SendOutDate_SendOut]);
    InBlock.gif                
    return entity;
    ExpandedSubBlockEnd.gif            }

    InBlock.gif            
    else
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    dot.gif{
    InBlock.gif                
    throw new ApplicationException("提示:您输入的行号有误!");
    ExpandedSubBlockEnd.gif            }

    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    设置实体值到DataTable#region 设置实体值到DataTable
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**////<summary>
    InBlock.gif        
    /// 设置实体值到DataTable
    InBlock.gif        
    ///</summary>
    InBlock.gif        
    ///<param name="baseEntity">实体</param>
    ExpandedSubBlockEnd.gif        
    ///<returns>是否设置成功</returns>

    InBlock.gif        public override bool SetEntity(BaseEntity baseEntity)
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    InBlock.gif            
    int rowIndex = baseEntity.RowIndex;
    InBlock.gif            SendOutEntity entity 
    = baseEntity as SendOutEntity;
    InBlock.gif            
    if (entity == null)
    InBlock.gif                
    return false;
    InBlock.gif            DataRow dr;
    InBlock.gif            
    if (rowIndex == -1)
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    dot.gif{
    InBlock.gif                dr 
    = this.NewRow();
    InBlock.gif
    InBlock.gif                dr[SendOutNo_SendOut] 
    = entity.SendOutNo;
    InBlock.gif                dr[InvoiceNo_SendOut] 
    = entity.InvoiceNo;
    InBlock.gif                dr[Amount_SendOut] 
    = entity.Amount;
    InBlock.gif                dr[UserName_SendOut] 
    = entity.UserName;
    InBlock.gif                dr[ChineseName_SendOut] 
    = entity.ChineseName;
    InBlock.gif                dr[CustomerCode_SendOut] 
    = entity.CustomerCode;
    InBlock.gif                dr[CustomerName_SendOut] 
    = entity.CustomerName;
    InBlock.gif                dr[Remark_SendOut] 
    = entity.Remark;
    InBlock.gif                dr[IsPaid_SendOut] 
    = entity.IsPaid;
    InBlock.gif                dr[SendOutDate_SendOut] 
    = entity.SendOutDate;
    InBlock.gif
    InBlock.gif                
    this.Rows.Add(dr);
    InBlock.gif                
    return true;
    ExpandedSubBlockEnd.gif            }

    InBlock.gif            
    else
    ExpandedSubBlockStart.gifContractedSubBlock.gif            
    dot.gif{
    InBlock.gif                
    if (rowIndex >= 0 && rowIndex < this.Rows.Count)
    ExpandedSubBlockStart.gifContractedSubBlock.gif                
    dot.gif{
    InBlock.gif                    
    try
    ExpandedSubBlockStart.gifContractedSubBlock.gif                    
    dot.gif{
    InBlock.gif                        dr 
    = this.Rows[rowIndex];
    InBlock.gif                        
    //只要是Key的值都不可以更改
    InBlock.gif
                            dr[InvoiceNo_SendOut] = entity.InvoiceNo;
    InBlock.gif                        dr[Amount_SendOut] 
    = entity.Amount;
    InBlock.gif                        dr[UserName_SendOut] 
    = entity.UserName;
    InBlock.gif                        dr[ChineseName_SendOut] 
    = entity.ChineseName;
    InBlock.gif                        dr[CustomerCode_SendOut] 
    = entity.CustomerCode;
    InBlock.gif                        dr[CustomerName_SendOut] 
    = entity.CustomerName;
    InBlock.gif                        dr[Remark_SendOut] 
    = entity.Remark;
    InBlock.gif                        dr[IsPaid_SendOut] 
    = entity.IsPaid;
    InBlock.gif                        dr[SendOutDate_SendOut] 
    = entity.SendOutDate;
    InBlock.gif                        
    return true;
    ExpandedSubBlockEnd.gif                    }

    InBlock.gif                    
    catch
    ExpandedSubBlockStart.gifContractedSubBlock.gif                    
    dot.gif{
    InBlock.gif                        
    return false;
    ExpandedSubBlockEnd.gif                    }

    ExpandedSubBlockEnd.gif                }

    InBlock.gif                
    else
    ExpandedSubBlockStart.gifContractedSubBlock.gif                
    dot.gif{
    InBlock.gif                    
    return false;
    ExpandedSubBlockEnd.gif                }

    ExpandedSubBlockEnd.gif            }

    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    ExpandedSubBlockEnd.gif    }

    ExpandedBlockEnd.gif}

     

    None.gifusing System;
    None.gif
    using System.Runtime.Serialization;
    None.gif
    using FishSky.Data.Base;
    None.gif
    None.gif
    namespace FishSky.Data.Chateau
    ExpandedBlockStart.gifContractedBlock.gif
    dot.gif{
    InBlock.gif    [Serializable]
    InBlock.gif    
    public class SendOutDataSet : BaseDataSet
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    dot.gif{
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    表格常量及数据表#region 表格常量及数据表
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    /// 定义对象数据集表:SendOutDataTable
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public SendOutDataTable SendOutTable = new SendOutDataTable();
    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    构造函数#region 构造函数
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    /// 构造函数
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public SendOutDataSet() : base()
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    序列化的构造函数#region 序列化的构造函数
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    /// 序列化的构造函数
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        public SendOutDataSet(SerializationInfo info, StreamingContext context) : base(info, context)
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    InBlock.gif
    ContractedSubBlock.gifExpandedSubBlockStart.gif        
    建立数据集的表格#region 建立数据集的表格
    InBlock.gif
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    /**//// <summary>
    InBlock.gif        
    /// 建立数据集的表格
    ExpandedSubBlockEnd.gif        
    /// </summary>

    InBlock.gif        protected override void BuildDataTables()
    ExpandedSubBlockStart.gifContractedSubBlock.gif        
    dot.gif{
    InBlock.gif            
    this.Tables.Add(SendOutTable);
    InBlock.gif            
    //设置新增自动生成key字段
    InBlock.gif
                this.KeyTypeID = "SendOutNo";
    ExpandedSubBlockEnd.gif        }

    InBlock.gif
    ExpandedSubBlockEnd.gif        
    #endregion

    ExpandedSubBlockEnd.gif    }

    ExpandedBlockEnd.gif}


      

    转载于:https://www.cnblogs.com/wildfish/archive/2005/12/29/307743.html

    展开全文
  • 继续完善我第一个Python程序。昨天晚上学了lambda,发现函数...我很怀疑下边这段代码自己3个月以后是否还能懂:囧#-*- coding: utf-8 -*-"""去除代码前行号Python小工具-lambda版Develop by YanXY"""import...

    继续完善我的第一个Python程序。

    昨天晚上学了lambda,发现函数编程真是个有趣的东西,对于某些应用(例如我的这个行号处理工具),可以极大减少代码书写量。不过函数编程也有缺点:代码可读性似乎很差。我很怀疑下边这段代码自己3个月以后是否还能看懂:囧

    #-*- coding: utf-8 -*-"""去除代码前行号的Python小工具-lambda版

    Develop by YanXY"""importsys, refromPyQt4importQtCore, QtGui

    app=QtGui.QApplication(sys.argv)

    window=QtGui.QWidget()

    window.resize(800,600)

    window.setWindowTitle(u'去除代码前行号的Python小工具 - lambda版 - Develop by YanXY')

    textBox=QtGui.QTextEdit()

    textBox.setAcceptRichText(bool(0))

    butOK=QtGui.QPushButton(u"去除行号")

    layout=QtGui.QHBoxLayout()

    layout.addWidget(textBox)

    layout.addWidget(butOK,alignment=QtCore.Qt.AlignTop)

    window.setLayout(layout)defCutLineNum():#核心在这,注意有个换行号,实际上只有一行代码,够酷吧 -_-textBox.setText(''.join(map(lambdax:re.compile(r'\D*\d+\s?[.|:|\]|\)]?\s?'). \

    sub('', x,count=1),unicode(textBox.toPlainText()).splitlines(1))))

    QtCore.QObject.connect(butOK,QtCore.SIGNAL("clicked()"),CutLineNum)

    window.show()

    sys.exit(app.exec_())

    下面我们就来自内而外层层解构这行代码(上边的阴影部分):

    (1)最内层是一个正则表达式替换,re.compile(r'\D*\d+\s?[.|:|\]|\)]?\s?')编译了了一个正则表达式,并返回了一个正则表达式对象。该正则表达式的含义请参看我的上一篇文章。

    (2)第二层:sub( '', x,count = 1 )的含义是用空字符替换字符串变量x中第一个匹配上述正则表达式的子串,也就是删除了x的行号。

    (3)第三层:用匿名函数将上述两层包装起来,这时需要用到lambda语句,它用来创建一个匿名函数(没和名字绑定的函数): 例如一个最简单的lambda函数形如

    lambdax: x+1#它等同于:defplus(x)returnx+1

    lambda的方便之处在于它可以少写一个函数定义,“减少键盘的敲击”(《可爱的Python》里说的,这本书里同时也提到滥用lambda会严重影响代码可读性)。

    (4)第四层,map函数,这是Python提供的一系列函数编程方法中的一个,t = map(func, s )函数将序列s中的每个元素传递给func函数做参数, 函数的返回值组成了列表 t, func函数必须有只有一个参数,例如:

    a=[1,2,3,4,5,6]deffoo(x):return3*x

    b=map(foo,a)#返回 b = [3, 6, 9, 12, 15, 18]

    以上代码引自《Python 精要参考(第二版)》,里边有更多函数编程的介绍。这本书非常不错,我现在用它以及上边提到的《可爱的Python》这两本书来学Python,向大家推荐。我是上网下载后打印的,各有100页左右(《可爱的Python》只打印了“语法篇”)。对初学者来说,这两本小书比《Python 学习手册》要好得多,《Python 学习手册》像砖头一样,反正我是没毅力看。

    在我的代码中,map函数用来从文本框中读取得字符串列表unicode(textBox.toPlainText()).splitlines(1))中,用第三层中的lambda函数替换每一行的行号,它返回了一个字符串列表(没有行号的)

    (5)第五层,join方法,用来把一个字符串列表连接为一个单一的字符串,这个比较简单,不再多说。

    (6)第六层,textBox.setText(……),把join后的字符串写回文本框,完成了。

    实际上以上的思路就是我在上一篇文章中写出来的代码,只不过此处通过函数编程手法,把那些循环、函数定义、赋值、取值等写在一行里了。

    方便吗?我觉得一点也没有,因为我的工作量是一样的,只不过少敲了几下键盘,(但多按了N次F5,调试总出错啊!)而且不太容易读懂。

    至于效率,我猜应该是一样的,Python在内部应该也是把这一条语句解析成上边的一串指令来执行。不然呢?

    展开全文
  • 特别是开发功能时候,有个感受就是刚刚开发完代码很清爽优雅,结果加了一大堆辅助代码后,整个代码就变得臃肿了,自己看着都挺难受。因此总想着能不能把这块写更优雅一点,今天本文就尝试探讨下“代码耗时统计”...

    一、前言

    代码耗时统计在日常开发中算是一个十分常见的需求,特别是在需要找出代码性能瓶颈时。

    可能也是受限于 Java 的语言特性,总觉得代码写起来不够优雅,大量的耗时统计代码,干扰了业务逻辑。特别是开发功能的时候,有个感受就是刚刚开发完代码很清爽优雅,结果加了一大堆辅助代码后,整个代码就变得臃肿了,自己看着都挺难受。因此总想着能不能把这块写的更优雅一点,今天本文就尝试探讨下“代码耗时统计”这一块。

    在开始正文前,先说下前提,“代码耗时统计”的并不是某个方法的耗时,而是任意代码段之间的耗时。这个代码段,可能是一个方法中的几行代码,也有可能是从这个方法的某一行到另一个被调用方法的某一行,因此通过 AOP 方式是不能实现这个需求的。

    二、常规方法

    2.1 时间差统计

    这种方式是最简单的方法,记录下开始时间,再记录下结束时间,计算时间差即可。

    public class TimeDiffTest{

    public static void main(String[] args) throws InterruptedException{

    final long startMs = TimeUtils.nowMs();

    TimeUnit.SECONDS.sleep(5); // 模拟业务代码

    System.out.println("timeCost: " + TimeUtils.diffMs(startMs));

    }

    }

    /* output:

    timeCost: 5005

    */

    public class TimeUtils{

    /**

    * @return 当前毫秒数

    */

    public static long nowMs(){

    return System.currentTimeMillis();

    }

    /**

    * 当前毫秒与起始毫秒差

    * @param startMillis 开始纳秒数

    * @return 时间差

    */

    public static long diffMs(long startMillis){

    return diffMs(startMillis, nowMs());

    }

    }

    这种方式的优点是实现简单,利于理解;缺点就是对代码的侵入性较大,看着很傻瓜,不优雅。

    2.2 StopWatch

    第二种方式是参考 StopWatch ,StopWatch 通常被用作统计代码耗时,各个框架和 Common 包都有自己的实现。

    public class TraceWatchTest{

    public static void main(String[] args) throws InterruptedException{

    TraceWatch traceWatch = new TraceWatch();

    traceWatch.start("function1");

    TimeUnit.SECONDS.sleep(1); // 模拟业务代码

    traceWatch.stop();

    traceWatch.start("function2");

    TimeUnit.SECONDS.sleep(1); // 模拟业务代码

    traceWatch.stop();

    traceWatch.record("function1", 1); // 直接记录耗时

    System.out.println(JSON.toJSONString(traceWatch.getTaskMap()));

    }

    }

    /* output:

    {"function2":[{"data":1000,"taskName":"function2"}],"function1":[{"data":1000,"taskName":"function1"},{"data":1,"taskName":"function1"}]}

    */

    public class TraceWatch{

    /** Start time of the current task. */

    private long startMs;

    /** Name of the current task. */

    @Nullable

    private String currentTaskName;

    @Getter

    private final Map> taskMap = new HashMap<>();

    /**

    * 开始时间差类型指标记录,如果需要终止,请调用 {@link #stop()}

    *

    * @param taskName 指标名

    */

    public void start(String taskName) throws IllegalStateException{

    if (this.currentTaskName != null) {

    throw new IllegalStateException("Can't start TraceWatch: it's already running");

    }

    this.currentTaskName = taskName;

    this.startMs = TimeUtils.nowMs();

    }

    /**

    * 终止时间差类型指标记录,调用前请确保已经调用

    */

    public void stop() throws IllegalStateException{

    if (this.currentTaskName == null) {

    throw new IllegalStateException("Can't stop TraceWatch: it's not running");

    }

    long lastTime = TimeUtils.nowMs() - this.startMs;

    TaskInfo info = new TaskInfo(this.currentTaskName, lastTime);

    this.taskMap.computeIfAbsent(this.currentTaskName, e -> new LinkedList<>()).add(info);

    this.currentTaskName = null;

    }

    /**

    * 直接记录指标数据,不局限于时间差类型

    *  @param taskName 指标名

    * @param data 指标数据

    */

    public void record(String taskName, Object data){

    TaskInfo info = new TaskInfo(taskName, data);

    this.taskMap.computeIfAbsent(taskName, e -> new LinkedList<>()).add(info);

    }

    @Getter

    @AllArgsConstructor

    public static final class TaskInfo{

    private final String taskName;

    private final Object data;

    }

    }

    我是仿照 org.springframework.util.StopWatch 的实现,写了 TraceWatch 类,这个方法提供了两种耗时统计的方法:

    通过调用 Start(name) 和 Stop() 方法,进行耗时统计。

    通过调用 Record(name, timeCost),方法,直接记录耗时信息。

    这种方式本质上和“时间差统计”是一致的,只是抽取了一层,稍微优雅了一点。

    注:你可以根据自己的业务需要,自行修改 TraceWatch 内部的数据结构,我这里简单起见,内部的数据结构只是随便举了个例子。

    三、高级方法

    第二节提到的两种方法,用大白话来说都是“直来直去”的感觉,我们还可以尝试把代码写的更简便一点。

    3.1 Function

    在 jdk 1.8 中,引入了 java.util.function 包,通过该类提供的接口,能够实现在指定代码段的上下文执行额外代码的功能。

    public class TraceHolderTest{

    public static void main(String[] args){

    TraceWatch traceWatch = new TraceWatch();

    TraceHolder.run(traceWatch, "function1", i -> {

    try {

    TimeUnit.SECONDS.sleep(1); // 模拟业务代码

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    });

    String result = TraceHolder.run(traceWatch, "function2", () -> {

    try {

    TimeUnit.SECONDS.sleep(1); // 模拟业务代码

    return "YES";

    } catch (InterruptedException e) {

    e.printStackTrace();

    return "NO";

    }

    });

    TraceHolder.run(traceWatch, "function1", i -> {

    try {

    TimeUnit.SECONDS.sleep(1); // 模拟业务代码

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    });

    System.out.println(JSON.toJSONString(traceWatch.getTaskMap()));

    }

    }

    /* output:

    {"function2":[{"data":1004,"taskName":"function2"}],"function1":[{"data":1001,"taskName":"function1"},{"data":1002,"taskName":"function1"}]}

    */

    public class TraceHolder{

    /**

    * 有返回值调用

    */

    public static  T run(TraceWatch traceWatch, String taskName, Supplier supplier){

    try {

    traceWatch.start(taskName);

    return supplier.get();

    } finally {

    traceWatch.stop();

    }

    }

    /**

    * 无返回值调用

    */

    public static void run(TraceWatch traceWatch, String taskName, IntConsumer function){

    try {

    traceWatch.start(taskName);

    function.accept(0);

    } finally {

    traceWatch.stop();

    }

    }

    }

    这里我利用了 Supplier 和 IntConsumer 接口,对外提供了有返回值和无返回值得调用,在 TraceHolder 类中,在核心代码块的前后,分别调用了前文的 TraceWatch 的方法,实现了耗时统计的功能。

    3.2 AutoCloseable

    除了利用 Function 的特性,我们还可以使用 jdk 1.7 的 AutoCloseable 特性。说 AutoCloseable 可能有同学没听过,但是给大家展示下以下代码,就会立刻明白是什么东西了。

    // 未使用 AutoCloseable

    public static String readFirstLingFromFile(String path) throws IOException{

    BufferedReader br = null;

    try {

    br = new BufferedReader(new FileReader(path));

    return br.readLine();

    } catch (IOException e) {

    e.printStackTrace();

    } finally {

    if (br != null) {

    br.close();

    }

    }

    return null;

    }

    // 使用 AutoCloseable

    public static String readFirstLineFromFile(String path) throws IOException{

    try (BufferedReader br = new BufferedReader(new FileReader(path))) {

    return br.readLine();

    }

    }

    在 try 后方可以加载一个实现了 AutoCloseable 接口的对象,该对象作用于整个 try 语句块中,并且在执行完毕后回调 AutoCloseable#close() 方法。

    让我们对 TraceWatch 类进行改造:

    「1.实现 AutoCloseable 接口,实现 close() 接口:」

    @Override

    public void close(){

    this.stop();

    }

    「2.修改 start() 方法,使其支持链式调用:」

    public TraceWatch start(String taskName) throws IllegalStateException{

    if (this.currentTaskName != null) {

    throw new IllegalStateException("Can't start TraceWatch: it's already running");

    }

    this.currentTaskName = taskName;

    this.startMs = TimeUtils.nowMs();

    return this;

    }

    public class AutoCloseableTest{

    public static void main(String[] args){

    TraceWatch traceWatch = new TraceWatch();

    try(TraceWatch ignored = traceWatch.start("function1")) {

    try {

    TimeUnit.SECONDS.sleep(1); // 模拟业务代码

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    try(TraceWatch ignored = traceWatch.start("function2")) {

    try {

    TimeUnit.SECONDS.sleep(1); // 模拟业务代码

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    try(TraceWatch ignored = traceWatch.start("function1")) {

    try {

    TimeUnit.SECONDS.sleep(1); // 模拟业务代码

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    System.out.println(JSON.toJSONString(traceWatch.getTaskMap()));

    }

    }

    /* output:

    {"function2":[{"data":1001,"taskName":"function2"}],"function1":[{"data":1002,"taskName":"function1"},{"data":1002,"taskName":"function1"}]}

    */

    四、总结

    本文列举了四种统计代码耗时的方法:

    时间差统计

    StopWatch

    Function

    AutoCloseable

    列举的方案是我目前能想到的方案。当然可能有更加优雅的方案,希望有相关经验的同学能在评论区一起交流下~

    END

    推荐好文

    展开全文
  • 后来很多优秀开源项目都相继蹦出来了,阅读的代码量那叫一个大呀!不得不。动机有三:文档不足、找问题的原因、好奇...  要想快速并高效地阅读源码,一定要有好方法,不然看着会挺费劲,当然,用什么方法取决于...
  • 如何快速给自己博客增加10000推荐 刚有个想法 用css改推荐,结果改完,博客好多地方都乱码了 也是醉了! 然后换ipad 还是乱码 博客也乱码了 哈哈。 注意,每次点推荐会涨10000个推荐! ...
  • 如何阅读别人C代码

    2012-10-13 22:28:00
     数据机构的试题中有两种情况,一个就是给你说了大致的程序功能和思想,让你补全你的程序,这种问题的麻烦就是不是自己完全的写作,以至于自己的代码,不是很好的适合出题者的思路。第二个就是给你一段程序让你读.....
  • 精简自己20%的代码

    2019-08-12 16:39:18
    先来说如何重构业务层try{}catch{}finally{}代码块,我过很多代码,异常处理这一块大致分为两种情况,一种是每个方法都大量充斥着try{}catch{}finally{},这种方式编程已经考虑到了异常处理,还有一种就是...
  • 如何阅读开源代码

    热门讨论 2011-11-08 22:53:06
    第一个好处是可以学习到很多编程的方法,看好的源代码,对于提高自己的 编程水平,比自己写源代码的帮助更大。当然不是说不用自己写,而是说,自己写代码的 同时,可以从别人写的好的源代码中间学习到更多的编程方法...
  • 如何阅读代码

    2009-09-28 22:12:00
    最近由于工作需要,要阅读大量的代码,但是了好长时间,不得要门,总感觉自己越读越糊涂,而且一个函数有写的很长,起来很费劲,里面的逻辑复杂,搞不清楚。完之后总是一头雾水。所以在网上搜了一下如何阅读...
  • Prism 是一个轻级并且简单易用的 JavaScript 类库,minified 和 gzipped 压缩后只有 1.5kb 大小,即使添加语言定义代码,最大也不会超过 2kb,是目前最小的代码高亮 Javascript 类库。 Prism 使用非常简单,只需...
  • 1.最近刚到公司,公司就发一架构代码自己看了几天的想吐,也在网上...后来很多优秀开源项目都相继蹦出来了,阅读的代码量那叫一个大呀!不得不。我现在掉到android这个大坑里,每天都要很多源代码。以前做...
  • 如何高效敲代码

    2020-07-29 23:32:54
    经常有读者对学习编程有一种困惑:书/视频都懂了,就是不会自己写。这也是当初行哥学编程时非常困扰的一个问题,之后不会写就对着敲代码 ... 如果只是照着别人的代码逐字敲进去,也只能练习手速,在大脑中暂时留下
  • 如何刷访问 详细介绍

    千次阅读 2019-07-16 11:22:58
    教大家一个简单又好用的刷访问的一个工具,我了其他人写的博客教大家刷访问都是用代码来实现的, 我教大家一个不一样的方法,还不用自己去复制代码去运行,有的代码还会报错让大家费时间来费劲,我的方法很...
  • 背景软件开发过程中,不可避免的是需要处理各种异常,就我自己来说,至少有一半...比较下面两张图,看看您现在编写的代码属于哪一种风格?然后哪种编码风格您更喜欢?丑陋的 try catch 代码块优雅的 Controller上...
  • 先来说如何重构业务层try{}catch{}finally{}代码块,我过很多代码,异常处理这一块大致分为两种情况,一种是每个方法都大量充斥着try{}catch{}finally{},这种方式编程已经考虑到了异常处理,还有一种就是...
  • 初学Java如何写好代码

    2018-03-03 14:14:00
    初学Java同学时常会遇到这样情况,跟着入门教程过一遍,但需要自己代码的时候却无从下手;写代码的时候时常会遇到不懂地方,如果停下来去详细了解,可能会花掉大量时间,如果跳过去,可能今后问题会越积...
  • 很难从头开始开发新代码,很多情况下都是以他人成果为基础的,或者新增修改需求,自己的代码也会被其他开发人员调用,所以写好一份高质量可维护的代码就显得十分重要。 2、什么是可维护代码# 可维护代码需要遵循...
  • 先来说如何重构业务层try{}catch{}finally{}代码块,我过很多代码,异常处理这一块大致分为两种情况,一种是每个方法都大量充斥着try{}catch{}finally{},这种方式编程已经考虑到了异常处理,还有一种就是...
  • 今天在IAP下载的时候发现需要知道自己编译出来的代码段的大小来设置FLASH的偏移,在keil下编译默认是会显示程序的大小的: 可以清除的看到代码(Code)占了29704个字节,只读常量(RO-data)占6456个字节,已...
  • 刚刚接触Java编程朋友总会遇到一些情况,比如:跟着Java基础教程过一遍后,自己代码的时候却无从下手;写代码的时候经常遇到不懂地方,如果停下来去详细了解,可能会花掉大量时间。如果跳过去,可能今后...
  • 网上资料非常少,甚至国外网站里对于二次开发经验贴也是寥寥无几,我最近接手了一个在Revit中做钢节点(包括创建钢板、焊缝、孔)项目,几乎是从零开始,各种方法都靠自己摸索,花了三个多月时间,费了很...
  • 其实这个很正常,刚开始学习写代码,都是跟着别人的套路往下写,的套路少,很难形成自己的套路,这就和做数学题是一样的,做一道题就想会所有的题目,这个可能性微乎其微,都是通过大量的练习来摸索到自己的套路.....
  • windows-如何复制大量文件

    千次阅读 2018-05-02 11:00:16
    有时候跳槽,公司的电脑是不能带走的,但是里面有自己很多的文件,想着复制到自己的硬盘里面做一个保存,这样以后万一想看看代码的话,就可以直接拿来看看于是上网搜寻,发现一款工具很是不错,软件名字:TeraCopy...
  • 编程有很大一部分时间是在阅读代码,不仅要阅读自己的代码,而且要阅读别人的代码。因此,可读性良好的代码能够大大提高编程效率。 可读性良好的代码往往会让代码架构更好,因为程序员更愿意去修改这部分代码,而且...
  • 正先给大家下实际效果,我在网上随便搜了一张帅哥证件照片试了下。基本上会把脑袋切出来,然后放大眼睛。 使用是开源项目:https://github.com/minivision-ai/photo2cartoon 具体原理直接摘录read.me一段...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,121
精华内容 448
关键字:

如何看自己的代码量