From d7051e152231209b748acefd92b72e32911aaaa6 Mon Sep 17 00:00:00 2001 From: liufuqiang Date: Mon, 11 Dec 2023 17:26:57 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=97=B6=E9=97=B4=E7=BB=9F=E8=AE=A1=E5=B7=A5?= =?UTF-8?q?=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/date/CodeWatchUtil.java | 144 ++++++++++++++++++ .../hutool/core/date/CodeWatchUtilTest.java | 51 +++++++ 2 files changed, 195 insertions(+) create mode 100644 hutool-core/src/main/java/org/dromara/hutool/core/date/CodeWatchUtil.java create mode 100644 hutool-core/src/test/java/org/dromara/hutool/core/date/CodeWatchUtilTest.java diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/CodeWatchUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/CodeWatchUtil.java new file mode 100644 index 000000000..5275d6da5 --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/CodeWatchUtil.java @@ -0,0 +1,144 @@ +package org.dromara.hutool.core.date; + +import org.dromara.hutool.core.text.StrUtil; +import org.dromara.hutool.core.thread.ThreadUtil; + +import java.util.concurrent.TimeUnit; + +/** + * 统计代码运行时间工具
+ * 此工具用于存储一组任务的耗时时间,并一次性打印对比,也可以打印每个任务运行时间
+ * + *

+ * 使用方法如下: + *

{@code
+ * CodeWatchUtil.init("任务id");
+ *
+ * // 任务1
+ * CodeWatchUtil.start("任务一");
+ * Thread.sleep(1000);
+ *
+ * // 任务2
+ * CodeWatchUtil.start("任务二");
+ * Thread.sleep(2000);
+ * Console.log(CodeWatchUtil.printCurrentTask());
+ *
+ * // 打印出耗时
+ * Console.log(CodeWatchUtil.prettyPrint());
+ *
+ * }
+ * + * @author liufuqiang + */ +public class CodeWatchUtil { + + private static ThreadLocal threadLocal = null; + + /** + * 初始化计时任务 + * + * @param id 用于标识秒表的唯一ID + */ + public static void init(String id) { + threadLocal = ThreadUtil.createThreadLocal(() -> StopWatch.of(id)); + } + + /** + * 创建计时任务
+ * 如果上一个任务未停止,可自动停止 + * + * @param taskName 任务名称 + */ + public static void start(String taskName) { + if (threadLocal == null) { + return; + } + + StopWatch stopWatch = threadLocal.get(); + if (stopWatch == null) { + return; + } + if (stopWatch.isRunning()) { + stopWatch.stop(); + } + stopWatch.start(taskName); + } + + /** + * 停止当前任务 + */ + public static void stop() { + if (threadLocal == null) { + return; + } + + StopWatch stopWatch = threadLocal.get(); + if (stopWatch == null) { + return; + } + if (stopWatch.isRunning()) { + stopWatch.stop(); + } + } + + /** + * 生成所有任务的一个任务花费时间表,单位纳秒 + * + * @return 任务时间表 + */ + public static String prettyPrint() { + return prettyPrint(null); + } + + /** + * 生成所有任务的一个任务花费时间表 + * + * @param unit 时间单位,{@code null}则默认{@link TimeUnit#NANOSECONDS} 纳秒 + * @return 任务时间表 + */ + public static String prettyPrint(TimeUnit unit) { + if (threadLocal == null) { + return null; + } + + StopWatch stopWatch = threadLocal.get(); + if (stopWatch == null) { + return null; + } + + if (stopWatch.isRunning()) { + stopWatch.stop(); + } + threadLocal.remove(); + return stopWatch.prettyPrint(unit); + } + + /** + * 打印当前任务执行时间 + * + * @return 当前任务运行时间 + */ + public static String printCurrentTask() { + return printCurrentTask(TimeUnit.NANOSECONDS); + } + + /** + * 打印当前任务执行的时间 + * + * @param unit 时间单位 + * @return 当前任务运行时间 + */ + public static String printCurrentTask(TimeUnit unit) { + if (threadLocal == null) { + return null; + } + + StopWatch stopWatch = threadLocal.get(); + if (stopWatch == null) { + return null; + } + StopWatch.TaskInfo taskInfo = stopWatch.getLastTaskInfo(); + return StrUtil.format("StopWatch '{}:' taskName:{} running time = {} {}", stopWatch.getId(), + taskInfo.getTaskName(), taskInfo.getTime(unit), DateUtil.getShortName(unit)); + } +} diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/CodeWatchUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/CodeWatchUtilTest.java new file mode 100644 index 000000000..0102f8d02 --- /dev/null +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/CodeWatchUtilTest.java @@ -0,0 +1,51 @@ +package org.dromara.hutool.core.date; + +import org.dromara.hutool.core.lang.Console; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.TimeUnit; + +/** + * @author: liufuqiang + * @date: 2023-12-11 17:04 + */ +public class CodeWatchUtilTest { + + @Test + public void printDefault() throws InterruptedException { + CodeWatchUtil.init("任务id"); + + // 任务1 + CodeWatchUtil.start("任务一"); + Thread.sleep(1000); + + // 任务2 + CodeWatchUtil.start("任务二"); + Thread.sleep(2000); + Console.log(CodeWatchUtil.printCurrentTask()); + + + // 打印出耗时 + Console.log(CodeWatchUtil.prettyPrint()); + } + + @Test + public void printUnit() throws InterruptedException { + CodeWatchUtil.init("任务id"); + method01(); + method02(); + Console.log(CodeWatchUtil.prettyPrint(TimeUnit.MILLISECONDS)); + } + + private static void method01() throws InterruptedException { + CodeWatchUtil.start("方法一"); + Thread.sleep(1000); + } + + private static void method02() throws InterruptedException { + CodeWatchUtil.start("方法二"); + Thread.sleep(2000); + CodeWatchUtil.stop(); + Console.log(CodeWatchUtil.printCurrentTask(TimeUnit.MILLISECONDS)); + } +} From a53a9da578d647aa41127ea5c95412742191d001 Mon Sep 17 00:00:00 2001 From: liufuqiang Date: Tue, 12 Dec 2023 15:36:49 +0800 Subject: [PATCH 2/4] add ByteUtil bitCount --- .../dromara/hutool/core/util/ByteUtil.java | 38 +++++++++++++++++++ .../hutool/core/util/ByteUtilTest.java | 17 +++++++++ 2 files changed, 55 insertions(+) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/util/ByteUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/util/ByteUtil.java index 4a2d8f14d..a7d29c29b 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/util/ByteUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/util/ByteUtil.java @@ -14,11 +14,14 @@ package org.dromara.hutool.core.util; import org.dromara.hutool.core.io.buffer.FastByteBuffer; import org.dromara.hutool.core.math.NumberUtil; +import org.dromara.hutool.core.text.StrUtil; import java.math.BigDecimal; import java.math.BigInteger; import java.nio.ByteOrder; import java.nio.charset.Charset; +import java.util.LinkedList; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.DoubleAdder; @@ -629,4 +632,39 @@ public class ByteUtil { } return buffer.toArrayZeroCopyIfPossible(); } + + /** + * 统计byte中位数为1的个数 + * + * @param buf 无符号bytes + * @return 为 1 的个数 + */ + public static int bitCount(final byte[] buf) { + int sum = 0; + for (byte b : buf) { + sum += Integer.bitCount((b & 0xFF)); + } + return sum; + } + + /** + * 统计无符号bytes转为bit位数为1的索引集合 + * + * @param bytes 无符号bytes + * @return 位数为1的索引集合 + */ + public static List toUnsignedBitIndex(final byte[] bytes) { + List idxList = new LinkedList<>(); + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(StrUtil.padPre(Integer.toBinaryString((b & 0xFF)), 8, "0")); + } + final String bitStr = sb.toString(); + for (int i = 0; i < bitStr.length(); i++) { + if (bitStr.charAt(i) == '1') { + idxList.add(i); + } + } + return idxList; + } } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/util/ByteUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/util/ByteUtilTest.java index ff645eebf..5b49fbe3b 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/util/ByteUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/util/ByteUtilTest.java @@ -12,11 +12,13 @@ package org.dromara.hutool.core.util; +import org.dromara.hutool.core.lang.Console; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.List; public class ByteUtilTest { @Test @@ -191,4 +193,19 @@ public class ByteUtilTest { aShort = wrap.getShort(); Assertions.assertEquals(a, aShort); } + + @Test + public void toUnsignedBitIndex() { + byte[] bytes = {0, 13, -64, -31, 101, 88, 47, -64}; + List list = ByteUtil.toUnsignedBitIndex(bytes); + Console.log(list); + } + + @Test + public void bitCount() { + byte[] bytes = {0, 13, -64, -31, 101, 88, 47, -64}; + int count = ByteUtil.bitCount(bytes); + Console.log(count); + Assertions.assertEquals(count, ByteUtil.toUnsignedBitIndex(bytes).size()); + } } From 21639023d6224e86ded0f7ebca10d656cf1a432b Mon Sep 17 00:00:00 2001 From: Faker <15641483049@163.com> Date: Tue, 12 Dec 2023 07:42:35 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20huto?= =?UTF-8?q?ol-core/src/main/java/org/dromara/hutool/core/date/CodeWatchUti?= =?UTF-8?q?l.java?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/date/CodeWatchUtil.java | 144 ------------------ 1 file changed, 144 deletions(-) delete mode 100644 hutool-core/src/main/java/org/dromara/hutool/core/date/CodeWatchUtil.java diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/CodeWatchUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/CodeWatchUtil.java deleted file mode 100644 index 5275d6da5..000000000 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/CodeWatchUtil.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.dromara.hutool.core.date; - -import org.dromara.hutool.core.text.StrUtil; -import org.dromara.hutool.core.thread.ThreadUtil; - -import java.util.concurrent.TimeUnit; - -/** - * 统计代码运行时间工具
- * 此工具用于存储一组任务的耗时时间,并一次性打印对比,也可以打印每个任务运行时间
- * - *

- * 使用方法如下: - *

{@code
- * CodeWatchUtil.init("任务id");
- *
- * // 任务1
- * CodeWatchUtil.start("任务一");
- * Thread.sleep(1000);
- *
- * // 任务2
- * CodeWatchUtil.start("任务二");
- * Thread.sleep(2000);
- * Console.log(CodeWatchUtil.printCurrentTask());
- *
- * // 打印出耗时
- * Console.log(CodeWatchUtil.prettyPrint());
- *
- * }
- * - * @author liufuqiang - */ -public class CodeWatchUtil { - - private static ThreadLocal threadLocal = null; - - /** - * 初始化计时任务 - * - * @param id 用于标识秒表的唯一ID - */ - public static void init(String id) { - threadLocal = ThreadUtil.createThreadLocal(() -> StopWatch.of(id)); - } - - /** - * 创建计时任务
- * 如果上一个任务未停止,可自动停止 - * - * @param taskName 任务名称 - */ - public static void start(String taskName) { - if (threadLocal == null) { - return; - } - - StopWatch stopWatch = threadLocal.get(); - if (stopWatch == null) { - return; - } - if (stopWatch.isRunning()) { - stopWatch.stop(); - } - stopWatch.start(taskName); - } - - /** - * 停止当前任务 - */ - public static void stop() { - if (threadLocal == null) { - return; - } - - StopWatch stopWatch = threadLocal.get(); - if (stopWatch == null) { - return; - } - if (stopWatch.isRunning()) { - stopWatch.stop(); - } - } - - /** - * 生成所有任务的一个任务花费时间表,单位纳秒 - * - * @return 任务时间表 - */ - public static String prettyPrint() { - return prettyPrint(null); - } - - /** - * 生成所有任务的一个任务花费时间表 - * - * @param unit 时间单位,{@code null}则默认{@link TimeUnit#NANOSECONDS} 纳秒 - * @return 任务时间表 - */ - public static String prettyPrint(TimeUnit unit) { - if (threadLocal == null) { - return null; - } - - StopWatch stopWatch = threadLocal.get(); - if (stopWatch == null) { - return null; - } - - if (stopWatch.isRunning()) { - stopWatch.stop(); - } - threadLocal.remove(); - return stopWatch.prettyPrint(unit); - } - - /** - * 打印当前任务执行时间 - * - * @return 当前任务运行时间 - */ - public static String printCurrentTask() { - return printCurrentTask(TimeUnit.NANOSECONDS); - } - - /** - * 打印当前任务执行的时间 - * - * @param unit 时间单位 - * @return 当前任务运行时间 - */ - public static String printCurrentTask(TimeUnit unit) { - if (threadLocal == null) { - return null; - } - - StopWatch stopWatch = threadLocal.get(); - if (stopWatch == null) { - return null; - } - StopWatch.TaskInfo taskInfo = stopWatch.getLastTaskInfo(); - return StrUtil.format("StopWatch '{}:' taskName:{} running time = {} {}", stopWatch.getId(), - taskInfo.getTaskName(), taskInfo.getTime(unit), DateUtil.getShortName(unit)); - } -} From ce543415f0cad7ebb3dfa6b797c63dccd6fa44d7 Mon Sep 17 00:00:00 2001 From: Faker <15641483049@163.com> Date: Tue, 12 Dec 2023 08:17:52 +0000 Subject: [PATCH 4/4] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20huto?= =?UTF-8?q?ol-core/src/test/java/org/dromara/hutool/core/date/CodeWatchUti?= =?UTF-8?q?lTest.java?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/date/CodeWatchUtilTest.java | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 hutool-core/src/test/java/org/dromara/hutool/core/date/CodeWatchUtilTest.java diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/CodeWatchUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/CodeWatchUtilTest.java deleted file mode 100644 index 0102f8d02..000000000 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/CodeWatchUtilTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.dromara.hutool.core.date; - -import org.dromara.hutool.core.lang.Console; -import org.junit.jupiter.api.Test; - -import java.util.concurrent.TimeUnit; - -/** - * @author: liufuqiang - * @date: 2023-12-11 17:04 - */ -public class CodeWatchUtilTest { - - @Test - public void printDefault() throws InterruptedException { - CodeWatchUtil.init("任务id"); - - // 任务1 - CodeWatchUtil.start("任务一"); - Thread.sleep(1000); - - // 任务2 - CodeWatchUtil.start("任务二"); - Thread.sleep(2000); - Console.log(CodeWatchUtil.printCurrentTask()); - - - // 打印出耗时 - Console.log(CodeWatchUtil.prettyPrint()); - } - - @Test - public void printUnit() throws InterruptedException { - CodeWatchUtil.init("任务id"); - method01(); - method02(); - Console.log(CodeWatchUtil.prettyPrint(TimeUnit.MILLISECONDS)); - } - - private static void method01() throws InterruptedException { - CodeWatchUtil.start("方法一"); - Thread.sleep(1000); - } - - private static void method02() throws InterruptedException { - CodeWatchUtil.start("方法二"); - Thread.sleep(2000); - CodeWatchUtil.stop(); - Console.log(CodeWatchUtil.printCurrentTask(TimeUnit.MILLISECONDS)); - } -}