From 649d41cd8a31178633de913e918c503ee7a95f40 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 7 Jun 2021 02:47:01 +0800 Subject: [PATCH] add jmh --- CHANGELOG.md | 1 + .../cn/hutool/core/collection/CollUtil.java | 32 ++++++-- .../cn/hutool/core/collection/IterUtil.java | 37 ++++++--- .../java/cn/hutool/core/util/StrUtilJmh.java | 77 +++++++++++++++++++ pom.xml | 2 +- 5 files changed, 131 insertions(+), 18 deletions(-) create mode 100644 hutool-core/src/test/java/cn/hutool/core/util/StrUtilJmh.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 49c9e4fe9..d03f4cb90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * 【http 】 ImgUtil增加getMainColor方法(pr#338@Gitee) * 【core 】 改进TreeUtil.buid算法性能(pr#1594@Github) * 【core 】 CsvConfig的setXXX返回this(issue#I3UIQF@Gitee) +* 【all 】 增加jmh基准测试 ### 🐞Bug修复 * 【core 】 修复FileUtil.normalize去掉末尾空格问题(issue#1603@Github) diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java index 7287eaf52..1c4353ea6 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java @@ -510,6 +510,24 @@ public class CollUtil { return IterUtil.countMap(null == collection ? null : collection.iterator()); } + /** + * 以 conjunction 为分隔符将集合转换为字符串 + * + * @param 集合元素类型 + * @param iterable {@link Iterable} + * @param conjunction 分隔符 + * @param func 集合元素转换器,将元素转换为字符串 + * @return 连接后的字符串 + * @see IterUtil#join(Iterator, CharSequence, Function) + * @since 5.6.7 + */ + public static String join(Iterable iterable, CharSequence conjunction, Function func) { + if (null == iterable) { + return null; + } + return IterUtil.join(iterable.iterator(), conjunction, func); + } + /** * 以 conjunction 为分隔符将集合转换为字符串
* 如果集合元素为数组、{@link Iterable}或{@link Iterator},则递归组合其为字符串 @@ -1617,9 +1635,9 @@ public class CollUtil { * @since 5.6.6 */ public static int lastIndexOf(Collection collection, Matcher matcher) { - if(collection instanceof List){ + if (collection instanceof List) { // List的查找最后一个有优化算法 - return ListUtil.lastIndexOf((List)collection, matcher); + return ListUtil.lastIndexOf((List) collection, matcher); } int matchIndex = -1; if (isNotEmpty(collection)) { @@ -2612,7 +2630,7 @@ public class CollUtil { * @since 5.4.7 */ public static void forEach(Iterable iterable, Consumer consumer) { - if(iterable == null){ + if (iterable == null) { return; } forEach(iterable.iterator(), consumer); @@ -2626,7 +2644,7 @@ public class CollUtil { * @param consumer {@link Consumer} 遍历的每条数据处理器 */ public static void forEach(Iterator iterator, Consumer consumer) { - if(iterator == null){ + if (iterator == null) { return; } int index = 0; @@ -2644,7 +2662,7 @@ public class CollUtil { * @param consumer {@link Consumer} 遍历的每条数据处理器 */ public static void forEach(Enumeration enumeration, Consumer consumer) { - if(enumeration == null){ + if (enumeration == null) { return; } int index = 0; @@ -2664,7 +2682,7 @@ public class CollUtil { * @param kvConsumer {@link KVConsumer} 遍历的每条数据处理器 */ public static void forEach(Map map, KVConsumer kvConsumer) { - if(map == null){ + if (map == null) { return; } int index = 0; @@ -2986,7 +3004,7 @@ public class CollUtil { * @author Looly */ @FunctionalInterface - public interface KVConsumer extends Serializable{ + public interface KVConsumer extends Serializable { /** * 接受并处理一对参数 * diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/IterUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/IterUtil.java index f2e6546f5..97d441c46 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/IterUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/IterUtil.java @@ -337,6 +337,31 @@ public class IterUtil { * @since 4.0.10 */ public static String join(Iterator iterator, CharSequence conjunction, String prefix, String suffix) { + return join(iterator, conjunction, (item)->{ + if (ArrayUtil.isArray(item)) { + return ArrayUtil.join(ArrayUtil.wrap(item), conjunction, prefix, suffix); + } else if (item instanceof Iterable) { + return join((Iterable) item, conjunction, prefix, suffix); + } else if (item instanceof Iterator) { + return join((Iterator) item, conjunction, prefix, suffix); + } else { + return StrUtil.wrap(String.valueOf(item), prefix, suffix); + } + }); + } + + /** + * 以 conjunction 为分隔符将集合转换为字符串
+ * 如果集合元素为数组、{@link Iterable}或{@link Iterator},则递归组合其为字符串 + * + * @param 集合元素类型 + * @param iterator 集合 + * @param conjunction 分隔符 + * @param func 集合元素转换器,将元素转换为字符串 + * @return 连接后的字符串 + * @since 5.6.7 + */ + public static String join(Iterator iterator, CharSequence conjunction, Function func) { if (null == iterator) { return null; } @@ -352,15 +377,7 @@ public class IterUtil { } item = iterator.next(); - if (ArrayUtil.isArray(item)) { - sb.append(ArrayUtil.join(ArrayUtil.wrap(item), conjunction, prefix, suffix)); - } else if (item instanceof Iterable) { - sb.append(join((Iterable) item, conjunction, prefix, suffix)); - } else if (item instanceof Iterator) { - sb.append(join((Iterator) item, conjunction, prefix, suffix)); - } else { - sb.append(StrUtil.wrap(String.valueOf(item), prefix, suffix)); - } + sb.append(func.apply(item)); } return sb.toString(); } @@ -826,7 +843,7 @@ public class IterUtil { * @since 5.5.0 */ public static int size(final Iterable iterable) { - if(null == iterable){ + if (null == iterable) { return 0; } diff --git a/hutool-core/src/test/java/cn/hutool/core/util/StrUtilJmh.java b/hutool-core/src/test/java/cn/hutool/core/util/StrUtilJmh.java new file mode 100644 index 000000000..e7a860723 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/util/StrUtilJmh.java @@ -0,0 +1,77 @@ +package cn.hutool.core.util; + +import cn.hutool.core.collection.CollUtil; +import lombok.Data; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime)//每次执行平均花费时间 +@Warmup(iterations = 5) //预热5次调用 +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) // 执行5此,每次1秒 +@Threads(1) //单线程 +@Fork(1) // +@OutputTimeUnit(TimeUnit.NANOSECONDS) // 单位:纳秒 +@State(Scope.Benchmark) // 共享域 +public class StrUtilJmh { + + @Benchmark + public void joinJmh() { + CollUtil.join(initSize(20), ",", (org)-> String.valueOf(org.getProvinceId())); + } + + @Benchmark + public void joinJmh2() { + final List orgs = initSize(20); + final Iterator iterator = orgs.iterator(); + + final StringBuilder sb = new StringBuilder(); + boolean isFirst = true; + while (iterator.hasNext()) { + if (isFirst) { + isFirst = false; + } else { + sb.append(","); + } + + sb.append(iterator.next().getProvinceId()); + } + sb.toString(); + } + + /** + * 来自:ibeetl + * 模拟测试数据,建议使用较大size以验证效果 + * @param size 数量 + * @return 对象List + */ + public static List initSize(int size){ + Org org = new Org(); + org.setProvinceId(21); + org.setName("北京"); + ArrayList list = new ArrayList<>(); + for(int i=0;i${lombok.version} test - + org.openjdk.jmh jmh-core