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的更多相关文章

  1. Java StringBuilder 高性能用法总结

    StringBuilder 误解: 1. Java编译优化后+和StringBuilder的效果一样: 2. StringBuilder不是线程安全的,为了"安全"起见最好还是用S ...

  2. Java 中 StringBuilder 在高性能用法总结

    关于StringBuilder,一般同学只简单记住了,字符串拼接要用StringBuilder,不要用+,也不要用StringBuffer,然后性能就是最好的了,真的吗吗吗吗? 还有些同学,还听过三句 ...

  3. StringBuilder在高性能场景下的正确用法

    转载:<StringBuilder在高性能场景下的正确用法> by 江南白衣 关于StringBuilder,一般同学只简单记住了,字符串拼接要用StringBuilder,不要用+,也不 ...

  4. Redis 数据结构之简单动态字符串SDS

    几个概念1:key对象 数据库存储键值对的键,总是一个字符串对象.2:value对象 数据库存储键值对的值,可以是字符串对象,list对象,hash对象,set对象,sorted set对象.    ...

  5. Netty高性能编程备忘录(下)

    估计很快就要被拍砖然后修改,因此转载请保持原文链接,否则视为侵权... http://calvin1978.blogcn.com/articles/netty-performance.html 前文再 ...

  6. StringBuilder_学习笔记

    参考:https://www.jianshu.com/p/160c9be0b132 连接符号 "+" 本质 字符串变量(非final修饰)通过 "+" 进行拼接 ...

  7. 唯品会Java开发手册》1.0.2版阅读

    <唯品会Java开发手册>1.0.2版阅读 1. 概述 <阿里巴巴Java开发手册>,是首个对外公布的企业级Java开发手册,对整个业界都有重要的意义. 我们结合唯品会的内部经 ...

  8. 【37】String,StringBuffer,StringBuilder区别和概念

    基本的概念: 查看 API 会发现,String.StringBuffer.StringBuilder 都实现了 CharSequence 接口,内部都是用一个char数组实现,虽然它们都与字符串相关 ...

  9. Redis数据结构之简单动态字符串SDS

    Redis的底层数据结构非常多,其中包括SDS.ZipList.SkipList.LinkedList.HashTable.Intset等.如果你对Redis的理解还只停留在get.set的水平的话, ...

随机推荐

  1. 3、尚硅谷_SSM高级整合_使用ajax操作实现增加员工的功能

    20.尚硅谷_SSM高级整合_新增_创建员工新增的模态框.avi 1.接下来当我们点击增加按钮的时候会弹出一个员工信息的对话框 知识点1:当点击新增的时候会弹出一个bootstrap的一个模态对话框 ...

  2. 03.基于测试开发讲解和Cobertura框架介绍

    首先我们先 CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(200) DEFAULT ...

  3. electron打造桌面应用

    Electron 将网页打包成桌面应用(web页面生成exe) http://m.blog.csdn.net/u014563989/article/details/75045052 Electron学 ...

  4. JS中style.display和style.visibility的区别

    在JS中可以通过设置style.display或者style.visibility属性来控制元素是否显示,在style.display=block和style.visibility=visible的时 ...

  5. Redis系列(八):发布与订阅

    Redis的发布与订阅,有点类似于消息队列,发送者往频道发送消息,频道的订阅者接收消息. 1. 发布与订阅示例 首先,在本机开启第1个Redis客户端,执行如下命令订阅blog.redis频道: SU ...

  6. python中lambda匿名函数与函数之间的关系

  7. 基础设计模式-03 从过滤器(Filter)校验链学习职责链模式

    1.职责链路模式 1.1UML图 1.2 职责链路模式的概念 为了避免处理对象的耦合关系,将对象连成一个链,沿着这个链进行访问,直到有一个对象处理位置: 1.3 优点 1.按照一定的顺序执行判断: 2 ...

  8. Redis四大模式之主从配置

    Redis工作模式主要有单机模式.主从模式(slave).哨兵模式(sentinel).集群模式(cluster)这四种,本文主要讲解一下主从模式的部署方式. 我是windows单机进行的这套搭建操作 ...

  9. python 魔法方法总结

    目录 一.__str__ 二.__repr__ 三.__format__ 四.__del__ 五.__dict__和__slots__ 六.__item__.__attr__系列 七.__init__ ...

  10. CTFHub_技能树_SQL注入Ⅱ

    SQL注入 MySQL结构 进行尝试: 尝试查看表名: 尝试查看列名: 发现无法直接输出: 使用时间注入脚本跑出结果: import requests import time session = re ...