SDS——重用StringBuilder
package example.java; /**
* @author 杜科
* @description 简单动态字符串,非线程安全。采取类似buffer的设计,使其成为一个可以方便重用的StringBuilder
* @contact AllenDuke@163.com
* @date 2020/6/9
*/
public class SDS implements Comparable<SDS>{ private int writePosition;//下一个要写的下标 private int capacity;//char数组大小 private char[] chars; private int hashcode=0; public SDS(){
this.capacity=40;
this.chars=new char[40];
} public SDS(int capacity){
this.capacity=capacity;
this.chars=new char[capacity];
} /**
*在使用sds时,尽量设定好最大容量,以减少扩容判断
*/ public SDS append(char ch){
if(writePosition==capacity) grow();
this.chars[writePosition++]=ch;
return this;
} public SDS append(String s){
if((this.capacity-this.writePosition)<s.length()) grow();//先一次判断扩容
for(int i=0;i<s.length();i++){
this.chars[writePosition++]=s.charAt(i);
}
// s.getChars(0, s.length(), chars, writePosition);
return this;
} public SDS append(SDS sds){
if((this.capacity-this.writePosition)<sds.length()) grow();//先一次判断扩容
for(int i=0;i<sds.length();i++){
this.chars[writePosition++]=sds.charAt(i);
}
return this;
} private void grow(){
int oldCapacity=capacity;
int newCapacity=capacity<<1;
char[] newChars=new char[newCapacity];
System.arraycopy(chars,0,newChars,0,oldCapacity);
capacity=newCapacity;
this.chars=newChars;
} public char charAt(int i){
return this.chars[i];
} public SDS setCharAt(int i, char ch){
this.chars[i]=ch;
return this;
} public SDS clear(){
this.writePosition=0;
this.hashcode=0;
return this;
} public int length(){
return this.writePosition;
} @Override
public int compareTo(SDS sds){
if(this.writePosition<sds.writePosition) return -1;
if(this.writePosition>sds.writePosition) return 1;
for(int i=0;i<writePosition;i++){
if(chars[i]<sds.charAt(i)) return -1;
if(chars[i]>sds.charAt(i)) return 1;
}
return 0;
} @Override
public int hashCode() {
if(hashcode!=0) return hashcode;
for(int i=0;i<writePosition;i++) hashcode=hashcode*31+chars[i];//与String的hashcode生成方法保持一致
return hashcode;
} @Override
public boolean equals(Object obj) {
if(this==obj) return true;
if(obj.hashCode()!=this.hashcode) return false;
if(!(obj instanceof SDS)) return false;
SDS sds= (SDS) obj;
if(sds.writePosition!=this.writePosition) return false;
for(int i=0;i<this.writePosition;i++){
if(sds.charAt(i)!=this.chars[i]) return false;
}
return true;
} @Override
public String toString() {
return new String(chars,0,writePosition);
} }
比起StringBuilder,SDS减少了大量无关紧要的运算,性能似乎比StringBuilder好。
简单测试
package example.java; /**
* @author 杜科
* @description 测试SDS可重用的性能
* @contact AllenDuke@163.com
* @date 2020/6/17
*/
public class SDSTest { private static int count=100000000; public static void main(String[] args) {
long start=System.currentTimeMillis()/1000;
testStringBuilder();
testSDS();
} public static void testStringBuilder(){
StringBuilder builder = new StringBuilder();
long time = System.currentTimeMillis();
for(int i=0;i<10000000;i++){
builder = new StringBuilder(40);
builder.append("aa");
builder.append("bb");
builder.append("cc");
builder.append("dd");
builder.append("ee");
builder.toString();
}
System.out.println("StringBuilder new 耗时:" + (System.currentTimeMillis() - time));
long time1 = System.currentTimeMillis();
StringBuilder builder1 = new StringBuilder(40);
for(int i=0;i<10000000;i++){
builder1.delete(0, builder.length());
builder1.append("aa");
builder1.append("bb");
builder1.append("cc“);
builder1.append("dd");
builder1.append("ee");
builder1.toString();
}
System.out.println("StringBuilder delete 耗时:" + (System.currentTimeMillis() - time1));
long time2 = System.currentTimeMillis();
StringBuilder builder2 = new StringBuilder(40);
for(int i=0;i<10000000;i++){
builder2.setLength(0);
builder2.append("aa");
builder2.append("bb");
builder2.append("cc");
builder2.append("dd");
builder2.append("ee");
builder2.toString();
}
System.out.println("StringBuilder setLenth=0 耗时:" + (System.currentTimeMillis() - time2));
} public static void testSDS(){
SDS sds;
long time = System.currentTimeMillis();
for(int i=0;i<10000000;i++){
sds = new SDS();
sds.append("aa");
sds.append("bb");
sds.append("cc");
sds.append("dd");
sds.append("ee");
sds.toString();
}
System.out.println("SDS new 耗时:" + (System.currentTimeMillis() - time));
long time2 = System.currentTimeMillis();
sds=new SDS();
for(int i=0;i<10000000;i++){
sds.clear();
sds.append("aa");
sds.append("bb");
sds.append("cc");
sds.append("dd");
sds.append("ee");
sds.toString();
}
System.out.println("SDS clear 耗时:" + (System.currentTimeMillis() - time2));
}
}
SDS——重用StringBuilder的更多相关文章
- Java StringBuilder 高性能用法总结
StringBuilder 误解: 1. Java编译优化后+和StringBuilder的效果一样: 2. StringBuilder不是线程安全的,为了"安全"起见最好还是用S ...
- Java 中 StringBuilder 在高性能用法总结
关于StringBuilder,一般同学只简单记住了,字符串拼接要用StringBuilder,不要用+,也不要用StringBuffer,然后性能就是最好的了,真的吗吗吗吗? 还有些同学,还听过三句 ...
- StringBuilder在高性能场景下的正确用法
转载:<StringBuilder在高性能场景下的正确用法> by 江南白衣 关于StringBuilder,一般同学只简单记住了,字符串拼接要用StringBuilder,不要用+,也不 ...
- Redis 数据结构之简单动态字符串SDS
几个概念1:key对象 数据库存储键值对的键,总是一个字符串对象.2:value对象 数据库存储键值对的值,可以是字符串对象,list对象,hash对象,set对象,sorted set对象. ...
- Netty高性能编程备忘录(下)
估计很快就要被拍砖然后修改,因此转载请保持原文链接,否则视为侵权... http://calvin1978.blogcn.com/articles/netty-performance.html 前文再 ...
- StringBuilder_学习笔记
参考:https://www.jianshu.com/p/160c9be0b132 连接符号 "+" 本质 字符串变量(非final修饰)通过 "+" 进行拼接 ...
- 唯品会Java开发手册》1.0.2版阅读
<唯品会Java开发手册>1.0.2版阅读 1. 概述 <阿里巴巴Java开发手册>,是首个对外公布的企业级Java开发手册,对整个业界都有重要的意义. 我们结合唯品会的内部经 ...
- 【37】String,StringBuffer,StringBuilder区别和概念
基本的概念: 查看 API 会发现,String.StringBuffer.StringBuilder 都实现了 CharSequence 接口,内部都是用一个char数组实现,虽然它们都与字符串相关 ...
- Redis数据结构之简单动态字符串SDS
Redis的底层数据结构非常多,其中包括SDS.ZipList.SkipList.LinkedList.HashTable.Intset等.如果你对Redis的理解还只停留在get.set的水平的话, ...
随机推荐
- java scoket Blocking 阻塞IO socket通信三
在NIO同步非阻塞的场景中和原来同步阻塞最大的却别就是引入了上面的Buffer对象,现在我们来学校上面的BUffer对象 我们来看看程序的代码: package bhz.nio.test; impor ...
- Redis:缓存淘汰策略
将redis用做缓存是一种非常常见的手段,然而由于内存大小的限制,会导致redis在内存空间满了以后需要处理继续存入的数据.总计有以下几种策略: volatile-ttl:在设置了过期时间的数据集里, ...
- django 分页器,序列化 ,MTV MVC
序列化组件## from django.core import serializers # django自带的一个小型的序列化工具# def reg(request):# user_list = mo ...
- 关于html属性中onSubmit事件属性的使用
看到一段onSubmit事件属性的例子,如下: <!DOCTYPE html> <html> <head> <script> function vali ...
- HTTP之User-Agent大全
User-Agent 首部包含了一个特征字符串,用来让网络协议的对端来识别发起请求的用户代理软件的应用类型.操作系统.软件开发商以及版本号. 以下是一些常见的各种浏览器的User-Agent: 1) ...
- CCNA-Part3 - 数据链路层的趣事 - 走进交换机
在这篇文章中,会先介绍局域网及其的组件,通过交换机延伸到 TCP/IP 中数据链路层,了解数据的传输介质,以及交换机的发展历程及原理. 最后介绍数据帧的格式. 在阅读后应该了解如下的内容: 什么是局域 ...
- 如何完美获得一个double值的整数部分
如果是java有float类型的向上取整:Math.ceil() //只要有小数都+1向下取整:Math.floor() //不取小数四舍五入:Math.round() //四舍五入 如果是C++:方 ...
- 队列的顺序存储与链式存储c语言实现
一. 队列 1.队列定义:只允许在表的一端进行插入,表的另一端进行删除操作的线性表. 2.循环队列:把存储队列的顺序队列在逻辑上视为一个环. 循环队列状态: 初始时:Q.front=Q.rear=0 ...
- Spring 获取单例流程(二)
读完这篇文章你将会收获到 Spring 中 prototype 类型的 bean 如何做循环依赖检测 Spring 中 singleton 类型的 bean 如何做循环依赖检测 前言 继上一篇文章 S ...
- CSS中link和@import的使用区别
我们都知道在html中引入外部的CSS 有2种方式,link标签和@import,他们又什么区别呢? 1.从属关系区别@import是 CSS 提供的语法规则,只有导入样式表的作用:link是HTML ...