• <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>

            The power of C, the power of MD

            A problem is a chance to do your best
            posts - 11, comments - 22, trackbacks - 0, articles - 0
              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            strcat在某種特定條件下的優(yōu)化

            Posted on 2010-07-28 21:46 roy 閱讀(2173) 評(píng)論(10)  編輯 收藏 引用 所屬分類(lèi): C/C++
            strcatC語(yǔ)言一個(gè)基本的字符串操作函數(shù),它的源代碼一般是這樣的。

            char *strcat(char *dest, const char *src)   
            {   
                
            char *tmp = dest;   
                
            while (*dest) dest++;   
                
            while ((*dest++ = *src++!= '\0');   
                
            return tmp;   
            }
              


            由此可見(jiàn),strcat調(diào)用時(shí),先移動(dòng)目標(biāo)字符串的指針到其尾部,再進(jìn)行復(fù)制。這種做法對(duì)于下標(biāo)比較大的數(shù)組重復(fù)調(diào)用時(shí),效率比較低。想象一下,第一次調(diào)用strcat時(shí),指針由0數(shù)到100,只不過(guò)復(fù)制了幾個(gè)字符,第二次調(diào)用strcat時(shí),指針又從0數(shù)到108,無(wú)論調(diào)用多少次,指針總是從0數(shù)起,就會(huì)知道這個(gè)時(shí)候是多么浪費(fèi)系統(tǒng)資源了!

            我找到一個(gè)辦法,字符串追加時(shí),事先給出目標(biāo)字符串結(jié)尾所在的位置,追加時(shí),也就不用從頭開(kāi)始計(jì)算其長(zhǎng)度了,復(fù)制的過(guò)程中,目標(biāo)字符串的結(jié)尾也隨之移動(dòng),下一次再追加也就可以使用它了。以下就是優(yōu)化過(guò)的string_append,與strcat相比,增加了一個(gè)整形指針以傳遞目標(biāo)字符串長(zhǎng)度的地址。

            /*
             * optimizer for strcat when appending to a large array again and again
             
            */

            char *string_append(char *dest, int *end, const char *src) {
                
            if ( *end >= 0 && dest && src ) {
                    
            char *= dest + *end;
                    
            while ( *p++ = *src++ ) (*end)++;
                }

                
            return dest;
            }


            經(jīng)試驗(yàn),string_append在大數(shù)組重復(fù)追加內(nèi)容的情形下,優(yōu)勢(shì)非常明顯。其它情形下,使用原來(lái)的strcat也就足夠了。

            #include <stdio.h>
            #include 
            <string.h>
            #include 
            <time.h>

            #define BUFF_SIZE 4096

            /*
             * optimizer for strcat when appending to a large array again and again
             
            */

            char *string_append(char *dest, int *end, const char *src) {
                
            if ( *end >= 0 && dest && src ) {
                    
            char *= dest + *end;
                    
            while ( *p++ = *src++ ) (*end)++;
                }

                
            return dest;
            }


            int main() {
                
            int i = 0, j = 0;
                
            int retry = 100000;
                
            int field = 100;
                
            char output1[BUFF_SIZE], output2[BUFF_SIZE];
                time_t time1 
            = time(NULL);
                
            for ( i = 0; i < retry; i++ ) {
                    memset(output1, 
            0, BUFF_SIZE);
                    
            int length = 0;
                    string_append(output1, 
            &length, "header\n");
                    
            for ( j = 0; j < field; j++ ) {
                        string_append(output1, 
            &length, "\tcall detail record ");
                        
            char c[8];
                        sprintf(c, 
            "%d", j);
                        string_append(output1, 
            &length, c);
                        string_append(output1, 
            &length, "\n");
                    }

                    string_append(output1, 
            &length, "trailer\n");
                }

                time_t time2 
            = time(NULL);
                printf(
            "It takes %d seconds to show the performance of string_append()\n", time2 - time1);

                time1 
            = time(NULL);
                
            for ( i = 0; i < retry; i++ ) {
                    memset(output2, 
            0, BUFF_SIZE);
                    strcat(output2, 
            "header\n");
                    
            for ( j = 0; j < field; j++ ) {
                        strcat(output2, 
            "\tcall detail record ");
                        
            char c[8];
                        sprintf(c, 
            "%d", j);
                        strcat(output2, c);
                        strcat(output2, 
            "\n");
                    }

                    strcat(output2, 
            "trailer\n");
                }

                time2 
            = time(NULL);
                printf(
            "It takes %d seconds to show the performance of strcat()\n", time2 - time1);
                
            if ( strcmp(output1, output2) )
                    printf(
            "They are NOT equal\n");
                
            else
                    printf(
            "They are equal\n");
                
            return 0;
            }

             

            -bash-3.2$ ./string_append_demo

            It takes 2 seconds to show the performance of string_append()

            It takes 11 seconds to show the performance of strcat()

            They are equal


            本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/yui/archive/2010/05/22/5616455.aspx

            Feedback

            # re: strcat在某種特定條件下的優(yōu)化  回復(fù)  更多評(píng)論   

            2010-07-28 23:55 by 陳梓瀚(vczh)
            所以C++的string類(lèi)都有記錄長(zhǎng)度的。

            # re: strcat在某種特定條件下的優(yōu)化  回復(fù)  更多評(píng)論   

            2010-07-29 00:57 by lwch
            沒(méi)有檢查緩沖區(qū)長(zhǎng)度...
            會(huì)造成溢出

            # re: strcat在某種特定條件下的優(yōu)化  回復(fù)  更多評(píng)論   

            2010-07-29 09:03 by roy
            @lwch

            原始的strcat一樣會(huì)溢出,這個(gè)問(wèn)題應(yīng)該由調(diào)用者負(fù)責(zé)

            # re: strcat在某種特定條件下的優(yōu)化[未登錄](méi)  回復(fù)  更多評(píng)論   

            2010-07-29 12:04 by c++
            我的程序里一直在strlen(name)。我想是該考慮string的記錄len。

            # re: strcat在某種特定條件下的優(yōu)化  回復(fù)  更多評(píng)論   

            2010-07-30 06:10 by hoodlum1980
            在現(xiàn)實(shí)應(yīng)用里,都是隨機(jī)化的處理,使用你的方法,實(shí)際上還需要求一次strlen,這樣也就沒(méi)有什么優(yōu)勢(shì)(和實(shí)用性)可言了。
            這是C字符串模型的一種特點(diǎn)(在這里體現(xiàn)出是缺點(diǎn),但在其他大部分地方都體現(xiàn)的是高效和靈活性)導(dǎo)致的,例如其他有些語(yǔ)言的字符串是在前面存儲(chǔ)字符串長(zhǎng)度的,但是這樣相對(duì)而言對(duì)字符串處理庫(kù)函數(shù)會(huì)提高一些維護(hù)難度,因?yàn)榭偸且瑫r(shí)照顧這個(gè)長(zhǎng)度信息。

            # re: strcat在某種特定條件下的優(yōu)化  回復(fù)  更多評(píng)論   

            2010-08-02 09:24 by roy
            @hoodlum1980

            這個(gè)例子中,從來(lái)沒(méi)用到strlen,而且,這是在某種特定條件下的優(yōu)化,初始值是空串,長(zhǎng)度為0,請(qǐng)看清楚

            # re: strcat在某種特定條件下的優(yōu)化  回復(fù)  更多評(píng)論   

            2010-08-04 09:16 by roy
            @hoodlum1980

            唉,我反而覺(jué)得你沒(méi)理解好,你是說(shuō)每次調(diào)用string_append都要先調(diào)用strlen嗎?根本不需要,每次string_append就已經(jīng)計(jì)算了下一次執(zhí)行時(shí)的偏移量了

            # re: strcat在某種特定條件下的優(yōu)化  回復(fù)  更多評(píng)論   

            2010-08-06 02:55 by hoodlum1980
            如果是每次你能知道是從哪里連接的場(chǎng)合,你只需要strcpy(s+length, src); 就好了呀。我的意思就是那個(gè)本來(lái)就是在常規(guī)場(chǎng)合使用的。也就是說(shuō),在你自己維護(hù)的上下文內(nèi),你當(dāng)然能夠盡可能的達(dá)到最精確的控制。但在各種交叉處理之中,strcat相對(duì)而言就是一種最通用和恰當(dāng)?shù)膸?kù)函數(shù)之一。同時(shí)C字符串在效率上給了你充分的自由度。我說(shuō)的就是在特定的應(yīng)用場(chǎng)合當(dāng)然可以根據(jù)其背景做出特定的優(yōu)化,但是要做通用性的實(shí)現(xiàn),因?yàn)榭紤]到通用性,不是所有的假設(shè)都能成立,特定的優(yōu)化可能因而不宜提供,這也是C字符串庫(kù)函數(shù)形成現(xiàn)在這個(gè)系列的原因了。

            # re: strcat在某種特定條件下的優(yōu)化  回復(fù)  更多評(píng)論   

            2010-08-06 03:02 by hoodlum1980
            簡(jiǎn)單說(shuō),strcat可以說(shuō)是strlen和strcpy的功能疊加。如果使用strcat,通常也就是不知道字符串長(zhǎng)度(但是要保證原來(lái)的空間足夠容納連接的字符串)或者不想關(guān)注這個(gè)信息的場(chǎng)合。如果你自己精確的知道或者已經(jīng)維護(hù)了這個(gè)信息,那么你當(dāng)然可以直接使用strcpy,是不是呢?這樣表達(dá)可能有點(diǎn)繞,如有不妥,當(dāng)我沒(méi)說(shuō)把。

            # re: strcat在某種特定條件下的優(yōu)化  回復(fù)  更多評(píng)論   

            2010-08-06 10:09 by roy
            @hoodlum1980

            首先感謝你一直關(guān)心拙作,我們都是技術(shù)人員,關(guān)于技術(shù)問(wèn)題沒(méi)什么不能談的,是嗎?

            其次,我并沒(méi)有用string_append代替strcat的意思,事實(shí)上,通常情況下,我都只用strcat,只有在strcat對(duì)效率影響實(shí)在太大的時(shí)候,才考慮string_append。這個(gè)例子中直接用strcpy當(dāng)然可以,但還是需要strlen計(jì)算附加串的長(zhǎng)度。
            久久棈精品久久久久久噜噜| 午夜天堂精品久久久久| 久久婷婷成人综合色综合| 亚洲七七久久精品中文国产| 99热精品久久只有精品| 久久国产欧美日韩精品| 狠狠综合久久AV一区二区三区 | 久久久免费观成人影院| 青青青青久久精品国产| 丰满少妇高潮惨叫久久久| 亚洲AV无码1区2区久久| 国内精品久久久久影院老司| 久久综合鬼色88久久精品综合自在自线噜噜| 日本免费一区二区久久人人澡| 精品乱码久久久久久久| 久久大香香蕉国产| 狠狠狠色丁香婷婷综合久久五月 | 久久精品黄AA片一区二区三区| 亚洲国产精品无码久久久蜜芽| 性色欲网站人妻丰满中文久久不卡| 欧美日韩精品久久久免费观看| 久久亚洲AV成人无码| 无码八A片人妻少妇久久| 亚洲国产美女精品久久久久∴| 天天爽天天狠久久久综合麻豆| www久久久天天com| 88久久精品无码一区二区毛片 | 777午夜精品久久av蜜臀| 亚洲人成网亚洲欧洲无码久久| 99久久精品国产一区二区 | 久久99热只有频精品8| 狠狠色噜噜狠狠狠狠狠色综合久久| 精品免费久久久久国产一区 | 伊人 久久 精品| 亚洲精品乱码久久久久久| 国产∨亚洲V天堂无码久久久 | 久久久久亚洲精品无码网址| 久久九九兔免费精品6| 九九久久99综合一区二区| 手机看片久久高清国产日韩| 久久久国产乱子伦精品作者|