• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評(píng)論-2670  文章-0  trackbacks-0
                Lazy Compiler使用Syngram動(dòng)態(tài)創(chuàng)建語(yǔ)法分析器的代碼實(shí)在是太慢了,debug竟然需要8秒鐘來(lái)處理91條比較長(zhǎng)的文法。于是我打開了Visual Studio 2008的Performance Wizard查看運(yùn)行時(shí)消耗的資源,結(jié)果發(fā)現(xiàn)竟然都消耗在自己那個(gè)array類的operator[]里面了。那一段代碼是用來(lái)檢查文法的左遞歸引用關(guān)系是否出現(xiàn)環(huán)的。結(jié)果就把用到的四個(gè)array全部換成bool*了,當(dāng)時(shí)只是為了創(chuàng)建二維數(shù)組方便使用了array類。

                過(guò)后,debug的時(shí)間立刻降為2秒鐘不到,于是我又打開Performance Wizard看了一次,這次消耗的瓶頸終于轉(zhuǎn)移到一個(gè)合理的地方了。

                結(jié)果:array竟然比指針慢了無(wú)窮多倍,得找個(gè)時(shí)候重新寫一次。不過(guò)這段代碼好象是去年寫的,也沒(méi)經(jīng)過(guò)什么性能測(cè)試,也難怪發(fā)現(xiàn)不了問(wèn)題。在此帖上代碼,等Lazy Script寫完了重新審查一下自己的那套模板庫(kù)(NTL,Non-standard Template Library,娃哈哈)。
              1     enum VLE_ArrayCommander
              2     {
              3         vacNewArray
              4     };
              5 
              6     template<VLE_ArrayCommander _Commander , VInt _Dims>
              7     class VL_ArrayDimension : public VL_Base
              8     {
              9     public:
             10         VInt    Dims[_Dims+1];
             11 
             12         VL_ArrayDimension()
             13         {
             14             for(VInt i=0;i<_Dims;i++)
             15             {
             16                 Dims[i]=0;
             17             }
             18         }
             19 
             20         VL_ArrayDimension(VInt Dim , VInt* PrevDims)
             21         {
             22             Dims[0]=Dim;
             23             memcpy(Dims+1,PrevDims,sizeof(VInt)*(_Dims-1));
             24         }
             25 
             26         VL_ArrayDimension<_Commander , _Dims+1> operator [](VInt Dim)
             27         {
             28             return VL_ArrayDimension<_Commander , _Dims+1>(Dim,Dims);
             29         }
             30 
             31         VInt GetSize()
             32         {
             33             VInt Size=1;
             34             for(VInt i=0;i<_Dims;i++)
             35             {
             36                 Size*=Dims[i];
             37             }
             38             return Size;
             39         }
             40     };
             41 
             42     extern VL_ArrayDimension<vacNewArray , 0> NewArray;
             43 
             44     template<typename _Type>
             45     class VL_ArrayInfo : public VL_Base
             46     {
             47     public:
             48         _Type*    Elements;
             49         VInt*    Dims;
             50         VInt    RefCount;
             51         VInt    Size;
             52 
             53         VL_ArrayInfo(VInt aDims)
             54         {
             55             Dims=new VInt[aDims];
             56         }
             57 
             58         ~VL_ArrayInfo()
             59         {
             60             delete[] Dims;
             61         }
             62     };
             63 
             64     template<typename _Type , VInt _Dims>
             65     class VL_Array : public VL_Base
             66     {
             67     protected:
             68 
             69     public:
             70 
             71         template<VInt _RefDims>
             72         class VL_ArrayReference : public VL_Base
             73         {
             74             friend class VL_Array;
             75         protected:
             76             VL_ArrayInfo<_Type>*    FInfo;
             77             _Type*                    FElements;
             78             VInt                    FSubSize;
             79         public:
             80 
             81             VL_ArrayReference(_Type* Elements , VL_ArrayInfo<_Type>* Info , VInt Dim)
             82             {
             83                 FInfo=Info;
             84                 FSubSize=FInfo->Size/FInfo->Dims[_RefDims];
             85                 FElements=Elements+Dim*FSubSize;
             86             }
             87 
             88             VL_ArrayReference(VL_ArrayInfo<_Type>* Info , _Type* Elements , VInt SubSize)
             89             {
             90                 FInfo=Info;
             91                 FElements=Elements;
             92                 FSubSize=SubSize;
             93             }
             94 
             95             VL_ArrayReference<_RefDims-1> operator [](VInt Dim)
             96             {
             97                 VInt SubSize=FSubSize/FInfo->Dims[_RefDims-1];
             98                 return VL_ArrayReference<_RefDims-1>(FInfo,FElements+Dim*SubSize,SubSize);
             99             }
            100 
            101             operator VL_Array<_Type , _RefDims>()
            102             {
            103                 return VL_Array<_Type , _Dims-1>(FInfo,FElements);
            104             }
            105 
            106             VL_Array<_Type , _RefDims> Reference()
            107             {
            108                 return VL_Array<_Type , _Dims-1>(FInfo,FElements);
            109             }
            110 
            111             VL_Array<_Type , _RefDims> Clone()
            112             {
            113                 return VL_Array<_Type , _Dims-1>(FInfo,FElements).Clone();
            114             }
            115 
            116             void Copy(VL_Array<_Type , _RefDims>& Array)
            117             {
            118                 VL_ArrayInfo<_Type>* ArrayInfo=Array.GetInfo();
            119                 VInt Count=FInfo->Dims[_RefDims-1];
            120                 if(Count>ArrayInfo->Dims[_RefDims-1])
            121                 {
            122                     Count=ArrayInfo->Dims[_RefDims-1];
            123                 }
            124                 for(VInt i=0;i<Count;i++)
            125                 {
            126                     operator [](i).Copy(Array[i].Reference());
            127                 }
            128             }
            129 
            130             VInt GetCount()
            131             {
            132                 return FInfo->Dims[_RefDims-1];
            133             }
            134         };
            135 
            136         template<>
            137         class VL_ArrayReference<1> : public VL_Base
            138         {
            139         protected:
            140             VL_ArrayInfo<_Type>*    FInfo;
            141             _Type*                    FElements;
            142         public:
            143 
            144             VL_ArrayReference(_Type* Elements , VL_ArrayInfo<_Type>* Info , VInt Dim)
            145             {
            146                 FInfo=Info;
            147                 FElements=Elements+Dim*FInfo->Size/FInfo->Dims[1];
            148             }
            149 
            150             VL_ArrayReference(VL_ArrayInfo<_Type>* Info , _Type* Elements , VInt SubSize)
            151             {
            152                 FInfo=Info;
            153                 FElements=Elements;
            154             }
            155 
            156             _Type& operator [](VInt Dim)
            157             {
            158                 return FElements[Dim];
            159             }
            160 
            161             operator VL_Array<_Type , 1>()
            162             {
            163                 return VL_Array<_Type , 1>(FInfo,FElements);
            164             }
            165 
            166             VL_Array<_Type , 1> Reference()
            167             {
            168                 return VL_Array<_Type , 1>(FInfo,FElements);
            169             }
            170 
            171             VL_Array<_Type , 1> Clone()
            172             {
            173                 return VL_Array<_Type , 1>(FInfo,FElements).Clone();
            174             }
            175 
            176             void Copy(VL_Array<_Type , 1>& Array)
            177             {
            178                 VL_ArrayInfo<_Type>* ArrayInfo=Array.GetInfo();
            179                 _Type* ArrayElements=Array.GetElements();
            180                 VInt Count=FInfo->Dims[0];
            181                 if(Count>ArrayInfo->Dims[0])
            182                 {
            183                     Count=ArrayInfo->Dims[0];
            184                 }
            185                 for(VInt i=0;i<Count;i++)
            186                 {
            187                     FElements[i]=ArrayElements[i];
            188                 }
            189             }
            190 
            191             VInt GetCount()
            192             {
            193                 return FInfo->Dims[0];
            194             }
            195         };
            196 
            197     protected:
            198         VL_ArrayInfo<_Type>*    FInfo;
            199         _Type*                    FElements;
            200 
            201         void Create(VInt Size)
            202         {
            203             FInfo=new VL_ArrayInfo<_Type>(_Dims);
            204             FInfo->Elements=new _Type[Size];
            205             FInfo->RefCount=1;
            206             FInfo->Size=Size;
            207             if(Size==0)
            208             {
            209                 for(VInt i=0;i<_Dims;i++)
            210                 {
            211                     FInfo->Dims[i]=0;
            212                 }
            213             }
            214             FElements=FInfo->Elements;
            215         }
            216 
            217         void Inc()
            218         {
            219             FInfo->RefCount++;
            220         }
            221 
            222         void Dec()
            223         {
            224             if(!--FInfo->RefCount)
            225             {
            226                 delete[] FInfo->Elements;
            227                 delete FInfo;
            228                 FInfo=0;
            229                 FElements=0;
            230             }
            231         }
            232 
            233         VL_Array(VInt Size)
            234         {
            235             Create(Size);
            236         }
            237 
            238     public:
            239 
            240         VL_Array()
            241         {
            242             Create(0);
            243         }
            244 
            245         VL_Array(VL_ArrayInfo<_Type>* Info , _Type* Elements)
            246         {
            247             FInfo=Info;
            248             FElements=Elements;
            249             Inc();
            250         }
            251 
            252         VL_Array(VL_ArrayDimension<vacNewArray , _Dims>& Dims)
            253         {
            254             Create(Dims.GetSize());
            255             memcpy(FInfo->Dims,Dims.Dims,sizeof(VInt)*_Dims);
            256         }
            257 
            258         ~VL_Array()
            259         {
            260             Dec();
            261         }
            262 
            263         VL_Array(VL_Array<_Type , _Dims>& Array)
            264         {
            265             FInfo=Array.FInfo;
            266             FElements=Array.FElements;
            267             Inc();
            268         }
            269 
            270         VL_Array<_Type , _Dims>& operator =(VL_Array<_Type , _Dims>& Array)
            271         {
            272             Dec();
            273             FInfo=Array.FInfo;
            274             FElements=Array.FElements;
            275             Inc();
            276             return *this;
            277         }
            278 
            279         VL_ArrayReference<_Dims-1> operator [](VInt Dim)
            280         {
            281             return VL_ArrayReference<_Dims-1>(FElements,FInfo,Dim);
            282         }
            283 
            284         VL_Array<_Type , _Dims> Reference()
            285         {
            286             return *this;
            287         }
            288 
            289         VL_Array<_Type , _Dims> Clone()
            290         {
            291             VL_Array<_Type , _Dims> Array(FInfo->Size);
            292             for(VInt i=0;i<FInfo->Size;i++)
            293             {
            294                 Array.FElements[i]=FElements[i];
            295             }
            296             memcpy(Array.FInfo->Dims,FInfo->Dims,sizeof(VInt)*_Dims);
            297             return Array;
            298         };
            299 
            300         void Copy(VL_Array<_Type , _Dims>& Array)
            301         {
            302             operator =(Array.Clone());
            303         }
            304 
            305         VL_ArrayInfo<_Type>* GetInfo()
            306         {
            307             return FInfo;
            308         }
            309 
            310         _Type* GetElements()
            311         {
            312             return FElements;
            313         }
            314 
            315         VInt GetCount()
            316         {
            317             return FInfo->Dims[_Dims-1];
            318         }
            319     };
            320 
            321     template<typename _Type>
            322     class VL_Array<_Type , 1> : public VL_Base
            323     {
            324     protected:
            325         VL_ArrayInfo<_Type>*    FInfo;
            326         _Type*                    FElements;
            327 
            328         void Create(VInt Size)
            329         {
            330             FInfo=new VL_ArrayInfo<_Type>(1);
            331             FInfo->Elements=new _Type[Size];
            332             FInfo->RefCount=1;
            333             FInfo->Size=Size;
            334             FInfo->Dims[0]=0;
            335             FElements=FInfo->Elements;
            336         }
            337 
            338         void Inc()
            339         {
            340             FInfo->RefCount++;
            341         }
            342 
            343         void Dec()
            344         {
            345             if(!--FInfo->RefCount)
            346             {
            347                 delete[] FInfo->Elements;
            348                 delete FInfo;
            349                 FInfo=0;
            350                 FElements=0;
            351             }
            352         }
            353 
            354         VL_Array(VInt Size)
            355         {
            356             Create(Size);
            357         }
            358 
            359     public:
            360 
            361         VL_Array()
            362         {
            363             Create(0);
            364         }
            365 
            366         VL_Array(VL_ArrayInfo<_Type>* Info , _Type* Elements)
            367         {
            368             FInfo=Info;
            369             FElements=Elements;
            370             Inc();
            371         }
            372 
            373         VL_Array(VL_ArrayDimension<vacNewArray , 1>& Dims)
            374         {
            375             Create(Dims.GetSize());
            376             FInfo->Dims[0]=Dims.Dims[0];
            377         }
            378 
            379         ~VL_Array()
            380         {
            381             Dec();
            382         }
            383 
            384         VL_Array(VL_Array<_Type , 1>& Array)
            385         {
            386             FInfo=Array.FInfo;
            387             FElements=Array.FElements;
            388             Inc();
            389         }
            390 
            391         VL_Array<_Type , 1>& operator =(VL_Array<_Type , 1>& Array)
            392         {
            393             Dec();
            394             FInfo=Array.FInfo;
            395             FElements=Array.FElements;
            396             Inc();
            397             return *this;
            398         }
            399 
            400         _Type& operator [](VInt Dim)
            401         {
            402             return FInfo->Elements[Dim];
            403         }
            404 
            405         VL_Array<_Type , 1> Reference()
            406         {
            407             return *this;
            408         }
            409 
            410         VL_Array<_Type , 1> Clone()
            411         {
            412             VL_Array<_Type , 1> Array(FInfo->Size);
            413             for(VInt i=0;i<FInfo->Size;i++)
            414             {
            415                 Array.FInfo->Elements[i]=FInfo->Elements[i];
            416             }
            417             return Array;
            418         };
            419 
            420         void Copy(VL_Array<_Type , 1>& Array)
            421         {
            422             operator =(Array.Clone());
            423         }
            424 
            425         VL_ArrayInfo<_Type>* GetInfo()
            426         {
            427             return FInfo;
            428         }
            429 
            430         _Type* GetElements()
            431         {
            432             return FElements;
            433         }
            434 
            435         VInt GetCount()
            436         {
            437             return FInfo->Dims[0];
            438         }
            439     };
            posted on 2008-04-27 19:53 陳梓瀚(vczh) 閱讀(2625) 評(píng)論(6)  編輯 收藏 引用 所屬分類: C++

            評(píng)論:
            # re: 今天發(fā)現(xiàn)自己的array類太慢 2008-04-27 20:06 | 空明流轉(zhuǎn)
            Release的照理沒(méi)那么慢。  回復(fù)  更多評(píng)論
              
            # re: 今天發(fā)現(xiàn)自己的array類太慢 2008-04-27 23:35 | 陳梓瀚(vczh)
            release只少了1/3,debug對(duì)array::operator[]加了太多東西了……  回復(fù)  更多評(píng)論
              
            # re: 今天發(fā)現(xiàn)自己的array類太慢 2008-06-02 00:20 | suxiaojack
            還是C的void*實(shí)現(xiàn)的任意類型的模板比較爽。速度最快。不同類型,不過(guò)是元素大小不同而已。  回復(fù)  更多評(píng)論
              
            # re: 今天發(fā)現(xiàn)自己的array類太慢 2008-06-02 10:00 | 陳梓瀚(vczh)
            void*的話為了把你需要的大于sizeof(void*)的東西放進(jìn)去,你將不得不malloc/free很多次,除非你有對(duì)象池,否則將在這里吃掉大量性能。  回復(fù)  更多評(píng)論
              
            # re: 今天發(fā)現(xiàn)自己的array類太慢 2008-07-24 09:24 | jetricy
            也難怪,雖然用了內(nèi)聯(lián),但是這個(gè)operator[]的指令數(shù)數(shù)10倍于尋址運(yùn)算了.
            另外記得inline優(yōu)化要在release中才有,N次尋址加上2次壓棧退棧,檢查棧操作,也就難怪了.  回復(fù)  更多評(píng)論
              
            # re: 今天發(fā)現(xiàn)自己的array類太慢 2009-08-03 16:47 | zdhsoft
            你的數(shù)組copy存在bug,當(dāng)自己copy自己的時(shí)候,會(huì)出現(xiàn)!  回復(fù)  更多評(píng)論
              
            日本免费久久久久久久网站 | 狠狠狠色丁香婷婷综合久久俺| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 久久精品国产亚洲Aⅴ蜜臀色欲| 国产成人无码精品久久久久免费 | 久久国产精品无码HDAV| 久久99精品国产自在现线小黄鸭| 国内精品久久久久久99蜜桃 | 久久久久国产一区二区三区| 97久久久久人妻精品专区| 狠狠色丁香久久综合五月| 亚洲精品美女久久久久99小说 | 77777亚洲午夜久久多喷| 久久久黄色大片| 亚洲av成人无码久久精品| 国产精品福利一区二区久久| 久久久久亚洲AV无码观看| 久久精品亚洲日本波多野结衣| 亚州日韩精品专区久久久| 久久久久亚洲av无码专区导航| 色综合久久88色综合天天 | 精品无码久久久久久久动漫| 无码八A片人妻少妇久久| 久久久一本精品99久久精品66| 久久久亚洲AV波多野结衣| 伊人久久大香线蕉无码麻豆| 久久综合精品国产一区二区三区| 精品久久久久久久国产潘金莲| 久久国产V一级毛多内射| 99久久国产综合精品成人影院| 久久久久久久久66精品片| 久久亚洲高清综合| 久久久久女教师免费一区| 很黄很污的网站久久mimi色| 国产99久久九九精品无码| 亚洲一区二区三区日本久久九| 久久精品国产亚洲沈樵| 一本大道加勒比久久综合| 国产精自产拍久久久久久蜜| 精品水蜜桃久久久久久久| 亚洲精品97久久中文字幕无码|