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. Bestcoder Round8

    4989Summary 既然用C++了就偷懒直接用STL大法了 #include<iostream> #include<algorithm> #include<vecto ...

  2. 黎活明8天快速掌握android视频教程--27_网络通信之通过GET和POST方式提交参数给web应用

    1该项目主要实现Android客户端以get的方式或者post的方式向java web服务器提交参数 Android客户端通过get方式或者post方式将参数提交给后台服务器,后台服务器对收到的参数进 ...

  3. 底层剖析Python深浅拷贝

    底层剖析Python深浅拷贝 拷贝的用途 拷贝就是copy,目的在于复制出一份一模一样的数据.使用相同的算法对于产生的数据有多种截然不同的用途时就可以使用copy技术,将copy出的各种副本去做各种不 ...

  4. 关于Java的jdbc中 DriverManager.registerDriver(driver); //注册驱动 有没有必要写的思考

    加载数据库驱动的时候,有如下部分代码: /1) 注册驱动程序 //给java.sql.Driver接口的引用赋值 com.mysql.jdbc.Driver 实现类对象// Driver driver ...

  5. NPM 配置文件修改

    NPM 配置文件修改 几乎每一门语言都有配套的包管理器,比如 Ruby 有 RubyGems,Go 有 go modules,npm 作为 node 的包管理器,你有想过全局安装的 node 包都放在 ...

  6. MTPuTTy使用

    在开发过程中我们常常会有连接远程 lunix 服务器的需求,这个时候我们需要一个工具来帮助我们做这件事,而这类工具就是远程连接工具.常见的工具有XShell,SecureCRT,Putty等.这里我选 ...

  7. Python实用笔记 (13)函数式编程——返回函数

    函数作为返回值 我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: def calc_sum(*args): ax = 0 for n in args: ax = ax + n ret ...

  8. webstorm 调试 typescript

    { "compilerOptions": { "target": "es5", "outFile": "bin ...

  9. 用JS实现改变文本框的只读属性

    <input id="aaa" readonly><input id="bbb" readonly> <script>doc ...

  10. Mac上使用Docker Desktop启动Kubernetes,踩坑后终于搞掂

    1 前言 Kubernetes又简称k8s,是Google开源的容器集群管理系统,最近也是火热.闲来无事(为了发文),捣鼓了一下,在Mac上搭建Kubernetes,遇到一些坑,也记录一下. 另外,D ...