首页IT科技c++大小写字母转换编程(C++中字母大小写转换实现的优化 程序即人生 博客频道 CSDN.NET)

c++大小写字母转换编程(C++中字母大小写转换实现的优化 程序即人生 博客频道 CSDN.NET)

时间2025-05-01 14:21:25分类IT科技浏览4311
导读:分类: 【C++】 【汇编】 2009-01-25 01:32 3678人阅读 评论(4 收藏 举报...

分类:

【C++】

【汇编】

2009-01-25 01:32 3678人阅读 评论(4) 收藏 举报

C++中字母大小写转换实现的优化

write by 九天雁翎

(JTianLing) --

blog.csdn.net/vagrxie

讨论新闻组及文件

在本文中全部以转换为小写为例           。

从推荐复用代码的角度来看            ,用库函数是不错的办法:

方案一:

char gc1[53] = "abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ";

void wayOne()

{

strlwr(gc1);

}

优点是使用方便                ,别人看着也容易理解     ,但是效率慢的让人吐血                 。

extern "C" char * __cdecl _strlwr (

char * string

)

{

if (__locale_changed == 0)

{

char * cp;

/* validation

section */

_VALIDATE_RETURN(string != NULL

,

EINVAL, NULL);

for (cp=string; *cp; ++cp)

{

if (A <= *cp && *cp <= Z)

*cp += a - A;

}

return(string);

}

else

{

_strlwr_s_l(string, (size_t

)(-1),

NULL);

return string;

}

}

循环中平均2.5次的判断            ,(*cp一次                 ,ifA<=一次     ,*cp<=版次)加平均每次0.5次的加法      ,虽然这样的转换O(n)是必不可少的                 ,但是对于这样多的操作还是慢的可怕     。

2

char gc2

[53]

= "abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ";

namespace MYTEST

{

inline char

*

strlwr(char *asz)

{

for(char

*

lp = gc2

;

*lp != 0; ++lp)

{

*lp |= 0x20;

}

return asz;

}

}

void wayTwo()

{

MYTEST::strlwr(gc2);

}

此例中利用了ASCII字母值的特点           ,一共只有一次判断(*lp=0,一次位或操作      。算法上提高了很多:)其实已经达到了1/3的效率提升                 。           。      。                 。           。

将原来一大堆的代码      ,转化成了反汇编只有4句的程序:

00401020 80 08 20orbyte ptr [eax],20h

00401023 83 C0 01addeax,1

00401026 80 38 00cmpbyte ptr [eax],0

00401029 75 F5jnewayTwo+10h (401020h)

但是考虑到char只是1个字节                 ,看到

00401020 80 08 20orbyte ptr [eax],20h

一句都感觉不爽           ,白白浪费了eax 这样4个字节的寄存器,于是可以这样优化:

namespace MYTEST2

{

inline char

*

strlwr(char *asz)

{

long* lp = (long*)gc3;

for(; *((char*)lp) != 0; ++lp)

{

(long)(*lp) |= 0x20202020;

}

for(char

*

lpc = (char*)lp;*lpc!=0; ++lpc)

{

*lpc |= 0x20;

}

return asz;

}

}

说实话                 ,。                 。                 。。           。                 。     。           。                 。     。      。没有任何清晰性可言                ,没有任何可读性可言,但是优化的思想就是充分的利用4个字节的寄存器            ,并且以DWORD来读取内存                ,这是很有效率的方式                 。汇编代码其实比C语言代码更加清晰     ,原因在于C语言代码还需要处理大量与类型相关的事情            ,汇编代码不需要           。

第一个循环汇编代码如下:

00401040 81 08 20 20 20 20 ordword ptr [eax],20202020h

00401046 83 C0 04addeax,4

00401049 80 38 00cmpbyte ptr [eax],0

0040104C 75 F2jnewayThree+10h (401040h)

将循环次数减少了3/4      。                 。           。。所以效率的优化还是很明显的                 。单指令多数据操作的思想不过就是这种思想的延生罢了                 。。           。呵呵                 ,但是说在前面     ,如此影响可读性的效率优化      ,除非在很必要的情况下                 ,不然慎用                 。     。           。                 。     。

为了证实效率的优化           ,起码也得给出一个测试结果给大家看看吧      ,不然还以为我胡扯了      。

void wayOne()

// Hit Count: 1

// Time: 5553.00

// Time with Children : 5553.00

{

strlwr(gc1);

}

void wayTwo()

// Hit Count: 1

// Time: 247.00

// Time with Children : 247.00

{

MYTEST::strlwr(gc2);

}

void wayThree()

// Hit Count: 1

// Time: 180.00

// Time with Children : 180.00

{

MYTEST2::strlwr(gc3);

}

int _tmain(int argc, _TCHAR* argv[])

// Hit Count: 1

// Time: 6836996435.00

// Time with Children : 6837002415.00

{

wayThree();

wayTwo();

wayOne();

}

测试结果为AQtime5测试数据                 ,单位为机器周期           ,因为结果已经很明显了,所以没有进行多次循环的测试                 。并且为了排除缓存的影响                 ,将最快的放在了最前面                ,那么哪怕有缓存的影响,对于wayThree也是最不利的才对           。库函数的5000多的结果            ,说慢的可怕并不为过      。在数据量很大的时候                ,这种优化的差异可不是一点点而已                 。

声明:本站所有文章     ,如无特殊说明或标注            ,均为本站原创发布           。任何个人或组织                 ,在未征得本站同意时     ,禁止复制           、盗用                 、采集     、发布本站内容到任何网站      、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益      ,可联系我们进行处理                 。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
seo外链专员是什么(网站seo外链该怎么做) vue怎么重新加载页面(解决在vue3中使用reactive响应式,赋值后造成页面不改变的问题?)