简述

有一个需求,是需要将URL中的query参数的key全部转换为小写或者大写,键值对的数量有点多,但全部都是英文字母,无需考虑非字母的情况。

实现比较快的做法是使用STL或C标准库中的转换接口,如下:

#include <string>
#include <cctype>
#include <algorithm> // 字符串中的大写字符转小写
std::string strtolower(std::string s)
{
transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
} // 字符串中的小写字符转大写
std::string strtoupper(std::string s)
{
transform(s.begin(), s.end(), s.begin(), ::toupper);
return s;
}

这个方法虽然很好,但是效率不是很高。

分析了一下ascii码的码值,发现大小写字母的ascii码之间是有规律的。

原理

英文字母的ASCII码值表示如下



对比一下其二进制形式



对比使用的是OSChina的在线工具http://tool.oschina.net/diff/

从对比的结果可以看出,大写字母与小写字母的差别仅是一个比特位的不同

因为它们的这个规律,可以写出下面的转换函数(如果输入不是字母,转出的结果会有错误)

可以查看数字0-9的ascii码值,可以看出它们的第6位都是0,所以转为小写的算法不会影响数字的值。

转小写算法中受到影响的,只有ascii码二进制表示中第六位为0的部分。其中非字母部分如下表

#include <iostream>
#include <string>
#include <stdint.h>
// 更优化
std::string strtoupper(std::string s)
{
if(s.empty()){return s;}
size_t len = s.size() + 1;
size_t alignlen = len + 8 - (len % 8);
s.resize(alignlen);
size_t ec = alignlen / 8;
uint64_t* p8 = (uint64_t*)s.data();
for(size_t i=0;i<ec;++i){
p8[i] &= 0xDFDFDFDFDFDFDFDF;
}
s.resize(len-1);
return s;
} // 未做进一步优化
std::string strtolower(std::string s)
{
size_t len = s.size();
size_t ec = len /8;
uint64_t* p8 = (uint64_t*)s.data();
for(size_t i=0;i<ec;++i){
p8[i] |= 0x2020202020202020;
}
uint8_t* p1 = (uint8_t*)(p8 + ec);
len %= 8;
for(size_t i=0;i<len;++i){
p1[i] |= 0x20;
}
return s;
}

性能测试

测试代码如下:

int main()
{
//std::cout << "Hello, world!\n";
for(size_t i=0;i<1000000;++i){
std::string s = strtoupper("qwertyuiopasdfghjklzxcvbnm````````QWERTYUIOPASDFGHJKLZXCVBNM");
//std::cout<<s<<std::endl;
s = strtolower("qwertyuiopasdfghjklzxcvbnm\t\t\t\t\t\t\t\tQWERTYUIOPASDFGHJKLZXCVBNM");
//std::cout<<s<<std::endl;
}
return 0;
}

--编译时候请勿优化,否则可能被优化掉!--

测试结果如下:

使用STL算法结果如下

time ./teststl
./teststl 7.88s user 0.03s system 100% cpu 7.904 total

自写代码测试结果如下

time ./test
./test 0.93s user 0.00s system 99% cpu 0.928 total

可以看到,其性能有差异。(应用场景有限)

C++高性能转换大小写算法的更多相关文章

  1. JS中应用正则表达式转换大小写

    JS中应用正则表达式转换大小写,代码很简单,看代码: 以下首字母大写,其它字母小写 <script type="text/javascript"> function r ...

  2. PHPStorm 使用正则批量查询替换并自动转换大小写的方法

    PHPStorm 的项目查询替换功能那是非常非常强大的, 速度也很快, 配合正则更加灵活强大. 一般的正则查询替换没什么太多好说的, 这里主要说说比较少用的 大小写自动转换的问题, 也是比较少用但很有 ...

  3. 用Java将字符串的首字母转换大小写

    在项目开发的时候会需要统一字符串的格式,比如首字母要求统一大写或小写,那用Java如何实现这一功能?下面一起来学习学习. 话不多说,直接上代码 ? 1 2 3 4 5 6 7 8 9 10 11 12 ...

  4. vscode代码段设置console.log,转换大小写,目录别名

    https://blog.csdn.net/gyz718/article/details/71513075 vscode代码段设置console.log https://blog.csdn.net/u ...

  5. Java 常用知识点汇总(数据类型之间转换、字符串的相关操作-截取、转换大小写等)

    1.Java四类八种数据类型 byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0 short:短整型,在内存中占16位,即2个字节,取值范围- ...

  6. golang []byte和string的高性能转换

    golang []byte和string的高性能转换 在fasthttp的最佳实践中有这么一句话: Avoid conversion between []byte and string, since ...

  7. 结合stack数据结构,实现不同进制转换的算法

    #!/usr/bin/env python # -*- coding: utf-8 -*- # learn <<Problem Solving with Algorithms and Da ...

  8. php字符串首字母转换大小写的实例分享

    php中对字符串首字母进行大小写转换的例子. in: 后端程序首字母变大写:ucwords() <?php $foo = 'hello world!'; $foo = ucwords($foo) ...

  9. java代码把字母转换大小写、、、、

    总结:从键盘输入多少次,就用for循环控制.这些需要输入的数据都放在循环内部,否则不会执行多次. package com.aaa; import java.util.Scanner; //大小写字母的 ...

随机推荐

  1. python的日志模块:logging;django的日志系统;django日志输出时间修改

    Django的log,主要是复用Python标准库中的logging模块,在settings.py中进行配置 源代码 1.__init__.py包含以下类: StreamHandler Formatt ...

  2. PL2303 Windows8.1驱动

    常用的USB转串口下载芯片驱动可以参照我这篇文章USB转串口 FT232/PL2303/CH340 驱动以及使用体会 ,今天有找出了那根串口线打算使用,由于系统已经换为Windows8.1 X64所以 ...

  3. ASP.NET MVC:WebPageRenderingBase.cs

    ylbtech-funcation-Utility: ASP.NET MVC:WebPageRenderingBase.cs 提供用于呈现使用 Razor 视图引擎的页的方法和属性. 1.A,WebP ...

  4. rapidjson库的基本使用

    转自:https://blog.csdn.net/qq849635649/article/details/52678822 我在工作中一直使用的是rapidjson库,这是我在工作中使用该库作的一些整 ...

  5. ds18b20驱动及应用程序

    ---------------------------------------------------------------------------------------------------- ...

  6. oracle的(+)

    (+)就是连接譬如SELECT a.*, b.* from a(+) = b就是一个右连接,等同于select a.*, b.* from a right join bSELECT a.*, b.* ...

  7. (转)AssetBundle系列——共享资源打包/依赖资源打包

    有人在之前的博客中问我有关共享资源打包的代码,其实这一块很简单,就两个函数: BuildPipeline.PushAssetDependencies():依赖资源压栈: BuildPipeline.P ...

  8. 最全的spark基础知识解答

    原文:http://www.36dsj.com/archives/61155 一. Spark基础知识 1.Spark是什么? UCBerkeley AMPlab所开源的类HadoopMapReduc ...

  9. 【nodejs】FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

    当使用大批量(>100)的SQL进行MySql数据库插值任务时,会发生以下错误: 总计将有371579条数据将被插入数据库 开始插入DB <--- Last few GCs ---> ...

  10. C++ 多态的原理

    1.多态解决什么问题? 面向抽象编程,用户不需要关心引用或者指针的真实类型,已经内部实现.2.C++ 要具备多态的性质,满足两个条件:表面类型和真实类型不一样,方法是虚方法.3.多态是如何实现的? 实 ...