- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个带有使用 picocli 3.9.6 的内部命令行的库。这些命令之一是 log
命令,它的工作方式与大多数记录器一样,采用日志级别和消息,以及其他几个选项。它在一些使用该库的应用程序中被多次调用,并且我们注意到,与将其切换为 picocli 相比,作为一次性执行此命令时,性能大幅下降。即使日志级别设置为没有任何有趣的事情发生,也是如此。两个版本的核心代码相同。
因此,我们怀疑 picocli 正在使用反射来处理每个命令实例。我们如何提高性能?我注意到 picocli 4.x 包含一个注释处理器,但让我们的用户使用 Graal 对我们来说是不现实的。由于注释不会跨实例更改,也许它们可以被缓存?log
的代码命令可以在这里找到:
https://github.com/soartech/jsoar/blob/maven/jsoar-core/src/main/java/org/jsoar/kernel/commands/LogCommand.java
我加了一个 testPerformance
单元测试在这里:https://github.com/soartech/jsoar/blob/maven/jsoar-core/src/test/java/org/jsoar/kernel/commands/LogCommandTest.java
在我的机器上运行单元测试会产生大约 3 秒的时间。如果我回去提交 2bc4d39549eeb4ad69fd45e97f9607475e6426d9
(2018 年 10 月 30 日),正好在 log
之前命令被转换为 picocli,并将测试放在那里(你可以用较新的版本替换整个单元测试文件),我得到了大约 0.03 秒的时间。
最佳答案
我使用 Java Flight Recorder 查看执行 LogCommandTest
时的热点是什么,并且我发现,确实,显示在顶部的本质上是 picocli 根据注释构建模型。
仔细一看,当前的应用逻辑重新初始化了一个新的CommandLine
带有 Log
新实例的模型每次调用 LogCommand
.这是确保每次调用都重置所有值的一种方法,但是当命令被大量调用时,成本会很高。幸运的是,这不是唯一的方法。
我建议您创建 CommandLine
对象一次,并将其重用于所有后续调用。 Picocli 旨在以这种方式使用:在解析新的用户输入之前,picocli 会将选项和参数重置为其默认值。
下面的补丁实现了这一点。我专注于LogCommand
因为这就是 OP 的内容,但您可能希望对其他频繁调用的性能敏感命令应用类似的更改。
我测试了下面的内容,发现 LogCommandTest.testPerformance
在我的机器上测试从 5 秒缩短到 0.5 秒。 LogCommandTest
中的其他测试还是通过。
建议补丁:
Index: jsoar-core/src/main/java/org/jsoar/kernel/commands/LogCommand.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jsoar-core/src/main/java/org/jsoar/kernel/commands/LogCommand.java (revision 576ae0a1420177bad69d2f9e2e0d405c74f87ab0)
+++ jsoar-core/src/main/java/org/jsoar/kernel/commands/LogCommand.java (date 1577052510919)
@@ -23,6 +23,7 @@
import org.jsoar.util.commands.SoarCommandContext;
import org.jsoar.util.commands.SoarCommandInterpreter;
+import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.HelpCommand;
import picocli.CommandLine.Model.CommandSpec;
@@ -39,17 +40,22 @@
{
private final Agent agent;
private SoarCommandInterpreter interpreter;
+ private Log log;
+ private CommandLine logCommand;
public LogCommand(Agent agent, SoarCommandInterpreter interpreter)
{
this.agent = agent;
this.interpreter = interpreter;
+ this.log = new Log(agent, interpreter, null);
+ this.logCommand = new CommandLine(log);
}
@Override
public String execute(SoarCommandContext context, String[] args) throws SoarException
{
- Utils.parseAndRun(agent, new Log(agent, interpreter, context), args);
+ this.log.context = context;
+ Utils.parseAndRun(agent, logCommand, args);
return "";
}
@@ -57,7 +63,7 @@
@Override
public Object getCommand()
{
- return new Log(agent,interpreter,null);
+ return logCommand;
}
@Command(name="log", description="Adjusts logging settings",
@@ -67,7 +73,7 @@
private final Agent agent;
private final LogManager logManager;
private final SoarCommandInterpreter interpreter;
- private final SoarCommandContext context;
+ private SoarCommandContext context;
private static String sourceLocationSeparator = ".";
@Spec
Index: jsoar-core/src/main/java/org/jsoar/kernel/commands/Utils.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jsoar-core/src/main/java/org/jsoar/kernel/commands/Utils.java (revision 576ae0a1420177bad69d2f9e2e0d405c74f87ab0)
+++ jsoar-core/src/main/java/org/jsoar/kernel/commands/Utils.java (date 1577052217242)
@@ -41,10 +41,25 @@
parseAndRun(command, args, ps);
}
-
+
+ /**
+ * Executes the specified command and returns the result.
+ * A command may be a user object or a pre-initialized {@code picocli.CommandLine} object.
+ * For performance-sensitive commands that are invoked often,
+ * it is recommended to pass a pre-initialized CommandLine object instead of the user object.
+ *
+ * @param command the command to execute; this may be a user object or a pre-initialized {@code picocli.CommandLine} object
+ * @param args the command line arguments (the first arg will be removed from this list)
+ * @param ps the PrintStream to print any command output to
+ * @return the command result
+ * @throws SoarException if the user input was invalid or if a runtime exception occurred
+ * while executing the command business logic
+ */
public static List<Object> parseAndRun(Object command, String[] args, PrintStream ps) throws SoarException {
- CommandLine commandLine = new CommandLine(command);
+ CommandLine commandLine = command instanceof CommandLine
+ ? (CommandLine) command
+ : new CommandLine(command);
// The "debug time" command takes a command as a parameter, which can contain options
// In order to inform picocli that the options are part of the command parameter
关于picocli - 如何在运行时提高命令性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59415247/
我有一个带有使用 picocli 3.9.6 的内部命令行的库。这些命令之一是 log命令,它的工作方式与大多数记录器一样,采用日志级别和消息,以及其他几个选项。它在一些使用该库的应用程序中被多次调用
我想用以下格式用 picocli 解析选项: application -mode CLIENT -c aaaa -d bbbb application -mode SERVER -e xxxx -f
如何支持所有(或部分)命令和子命令的共享选项?例如,如果最终用户在命令行参数中的任何位置提供 --stacktrace,则打印的任何错误都将包含堆栈跟踪。 我们可以使用 Mixin 定义一个 bool
我正在从 picocli 3.9.6 更新到 4.2.0,在用新版本替换旧的已弃用调用时遇到了问题。 在我的原始版本中,我有一个这样的代码块: try { return commandLine
我想为我的程序提供一个搜索字符串,例如: cmd.execute("getDevices", "-h 1.2.3.4", "-p myPSW", "-u myUser", "-n red|blue&b
我一直在尝试一些 C 解释器并发现picoC 看起来可以满足我的所有需求。 启动您调用的脚本void PicocCallMain(int argc, char **argv);它递归地调用内部解析器等
Picocli v2.3.0。 @CommandLine.Option(names = {"--number-headings"}, arity = "0..1
我正在使用 picocli java 命令行库来实现命令行应用程序。但是,我想知道 picocli 是否提供了一种功能,可以帮助处理命令行不接收任何参数或选项(默认情况下)的情况。 谢谢 最佳答案 我
我有一个带有命令行变量的工作项目。当我使用命令行选项在 IntelliJ 中运行它时它可以工作,我如何将它变成一个完整的终端命令? 最佳答案 picocli 用户手册有两个可能相关的部分: Runni
我正在尝试使用 PICOCLI 在 Java 中构建 CLI,但我在一个非常基本的点上陷入困境。我根本无法让我的应用程序向消费者提供一个选项和它的值(value)。这是我的课: package c
我正在使用picocli实现一个 cli 工具,我有一个如下所示的命令。 mainCommand subCommand : parameter3 我的问题是如何映射 parameter和paramet
我尝试实现我自己的 CLI 并想使用 picocli 来解析我的命令的参数。这就是为什么我根本不想让 picocli 在控制台中写入。所以我创建了带有一些选项和参数注释的类 MyCommand。现在我
我有一个带有子命令的命令。在我的应用程序中,我希望用户必须指定一个子命令。我应该怎么做? (另见 https://github.com/remkop/picocli/issues/529) 最佳答案
我有一个用例,我需要以指定的格式发布 CLI 的完整帮助。我找到了一种使用以下方法来做到这一点的方法: @CommandLine.Command(name="myAp", synops
我遇到的情况是,我需要三个强制参数(field1、field2 和 field3。然后我希望用户输入a 命令名称(必填,值可以是create、list等)。命令名称必须输入,并且必须是单数(仅可以输入
我遇到的情况是,我需要三个强制参数(field1、field2 和 field3。然后我希望用户输入a 命令名称(必填,值可以是create、list等)。命令名称必须输入,并且必须是单数(仅可以输入
@Parameters(index = "0") private Double min_c_re; @Parameters(index = "1") private Double min_c_im;
假设我的项目执行大量逻辑,并且有一些入口点,它们是 CLI 命令。 我用@Command注释我的入口点,初始化我的@Parameters和@Option注释字段并执行逻辑,这并不不再需要 CLI。 据
我有这样的选择 @CommandLine.Option(names = "-D", description = "Define a symbol.") /* A list of def
我刚刚偶然发现 picoc它的功能给我留下了深刻的印象——尤其是它可以通过添加新功能等进行扩展这一事实。它使我免于走上尝试“推出自己的”解释器的道路。 但是,我想知道我是否可以通过以下方式扩展 pic
我是一名优秀的程序员,十分优秀!