C++高性能转换大小写算法
简述
有一个需求,是需要将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++高性能转换大小写算法的更多相关文章
- JS中应用正则表达式转换大小写
JS中应用正则表达式转换大小写,代码很简单,看代码: 以下首字母大写,其它字母小写 <script type="text/javascript"> function r ...
- PHPStorm 使用正则批量查询替换并自动转换大小写的方法
PHPStorm 的项目查询替换功能那是非常非常强大的, 速度也很快, 配合正则更加灵活强大. 一般的正则查询替换没什么太多好说的, 这里主要说说比较少用的 大小写自动转换的问题, 也是比较少用但很有 ...
- 用Java将字符串的首字母转换大小写
在项目开发的时候会需要统一字符串的格式,比如首字母要求统一大写或小写,那用Java如何实现这一功能?下面一起来学习学习. 话不多说,直接上代码 ? 1 2 3 4 5 6 7 8 9 10 11 12 ...
- vscode代码段设置console.log,转换大小写,目录别名
https://blog.csdn.net/gyz718/article/details/71513075 vscode代码段设置console.log https://blog.csdn.net/u ...
- Java 常用知识点汇总(数据类型之间转换、字符串的相关操作-截取、转换大小写等)
1.Java四类八种数据类型 byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0 short:短整型,在内存中占16位,即2个字节,取值范围- ...
- golang []byte和string的高性能转换
golang []byte和string的高性能转换 在fasthttp的最佳实践中有这么一句话: Avoid conversion between []byte and string, since ...
- 结合stack数据结构,实现不同进制转换的算法
#!/usr/bin/env python # -*- coding: utf-8 -*- # learn <<Problem Solving with Algorithms and Da ...
- php字符串首字母转换大小写的实例分享
php中对字符串首字母进行大小写转换的例子. in: 后端程序首字母变大写:ucwords() <?php $foo = 'hello world!'; $foo = ucwords($foo) ...
- java代码把字母转换大小写、、、、
总结:从键盘输入多少次,就用for循环控制.这些需要输入的数据都放在循环内部,否则不会执行多次. package com.aaa; import java.util.Scanner; //大小写字母的 ...
随机推荐
- [转]Nginx 502 PHP LNMP 502 终极解决方案 完美解决502 用 upstream 和 fastcgi_next_upstream 可以极大缓解
转: http://xn--ghqyhzj.com/post-21537.html 本文针对LNMP的PHP 版本ver 5.3.6 or Higher,其它未测试过. 1. 使用不同端口或php-f ...
- Mockito 的使用
转自:Mockito 中文文档 ( 2.0.26 beta ) 转自:手把手教你 Mockito 的使用 参数匹配器 Argument Matcher(参数匹配器) Mockito通过equals() ...
- 学习笔记:Maven的ArcheType的学习笔记
摘要: Archetype是什么?它由哪些文件组成?如何创建和安装自己的archtype,如何使用自己创建的archetype? 一.Archetype是什么 Archetype其实就 ...
- WebView JS交互 JSBridge 案例 原理 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- js时间戳怎么转成日期格式
原文地址:http://www.sufeinet.com/thread-1500-1-1.html js时间戳怎么转成日期格式这个在主群里有朋友§☆釺哖蟲...o问js时间戳怎么转成日期格式 ,他的问 ...
- 【Spark】Spark-空RDD判断与处理
Spark-空RDD判断与处理 SparkKafkaDemo - Streaming Statistics rdd isempty count_百度搜索 Spark RDD.isEmpty costs ...
- mono touch登录设计
需要对MonoTouch.Dialog-1进行引用: using System; using System.Collections.Generic; using System.Linq; using ...
- 原:wireshare使用技巧收集
/data/local/tcpdump -p -vv -s 0 -w /sdcard/ThinkDrive.pcap 先抓一个pcap的包. 1. 查看所有的链接与流量 统计->对话 这 ...
- Java归去来第4集:java实战之Eclipse中创建Maven类型的SSM项目
一.前言 如果还不了解剧情,请返回第3集的剧情 Java归去来第3集:Eclipse中给动态模块升级 二.在Eclipse中创建Maven类型的SSM项目 2.1:SSM简介 SSM ...
- Coursera公开课笔记: 斯坦福大学机器学习第六课“逻辑回归(Logistic Regression)” 清晰讲解logistic-good!!!!!!
原文:http://52opencourse.com/125/coursera%E5%85%AC%E5%BC%80%E8%AF%BE%E7%AC%94%E8%AE%B0-%E6%96%AF%E5%9D ...