简述

有一个需求,是需要将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. PHP Unit资料收集

    ThinkPHP Unit https://github.com/gaoermai/ThinkPHPUnit PHPUnit入门http://blog.csdn.net/fly_heart_yuan/ ...

  2. 检测ASP.NET是否是调试模式

    在web.config里,可以设置debug为true或者false <system.web> <compilation debug="false" target ...

  3. libc中的标准函数 localtime和localtime_r 的用法

    http://baike.baidu.com/view/1080853.htm 随便一查,就可以查到基本用法,但是... http://blog.csdn.net/maocl1983/article/ ...

  4. RV32M指令集

    Risc-V定义了可选的RV32M,它定义了整数乘法除法指令. 总共8条指令. Category Fmt RV32I base machine code(bin) comment mul 整数乘法 R ...

  5. android adb源码分析(1)

    ADB是Android debug bridge的缩写,它使用PC机可以通过USB或网络与android设备通讯. adb的源码位于system/core/adb目录下,先来看下编译脚本Android ...

  6. C# Winform 未能加载文件或程序集"System.Data.SQLite"或它的某一个依赖项。试图加载格式不正确的程序

    在使用Winform 开发了一个小软件,其中使用了SQLite作为数据库 但在我的Win7 64位系统上却出现了以下错误: System.BadImageFormatException: 未能加载文件 ...

  7. ESXI部署OVF模板提示用户已取消操作处理方法

    ESXI导出OVF部署到新的ESXI服务器上,Linux主机没有出现用户已取消操作的提示,部署WINDOW虚拟机的时候,提示用户已取消操作,如图: ​首先,要先了解为什么会出现这个问题,原因在于,在做 ...

  8. Sql控制反转小尝试

    假想用配置Sql语句的方式来完毕一个处理逻辑,而且映射到一个Url,这样当请求这个url的时候,运行前面配置的sql. 以下的一段详细配置,比如 当请求pagerlistdept.do的时候,会传入參 ...

  9. 前端html用一个表单来映射后台多个对象

    public class entity1 { private String id; public String getId() { return id; } public void setId(Str ...

  10. 【Python】使用torrentParser1.02对单文件torrent的分析结果

    C:\Users\horn1\Desktop\python\41-torrentParser>python torrentParser.py 文件名=./5.torrent 文件结构: anno ...