我的Web项目中有超过2000个JS文件要格式化。 我知道谷歌封闭编译器擅长这样做,实际上我用它来编写整个JS文件格式的工具。 我的要求是格式化的JS文件将在同一个地方替换原始文件。
我写了一个Java程序来查找web项目中的每个JS文件,当找到一个文件时,一个线程将负责执行命令
java -jar compiler.jar --js C:/project/xyz/abc.js --js_output_file C:/project/xyz/abc.js`原始的JS文件(abc.js)将被格式化。
但我发现这种方式效率不高。 问题是我使用ExecutorService来运行线程,每个线程花大约10秒来完成文件的格式化。 所以你可以想象完成超过2000个文件需要多长时间。
以下是代码段。
ExecutorService executor = Executors.newFixedThreadPool(10); // ... for(File jsFile : root.listFiles()) { Runnable formatThread = new FormatThread(jsFilePath.getAbsolutePath()); //execute command "java -jar compiler.jar in run(), handled by ProcessBuilder executor.execute(formatThread); }我已经尝试增加线程池大小,但程序启动后CPU和内存很快就消耗殆尽。
我的问题是
用Java编写的应用程序格式化大量文件的有效方法是什么? 在我的程序中使用ExecutorService是否正确并适合我的用例? 任何其他Java API都可以快速格式化Javascript文件? 实际上我需要的只是删除空行和用户注释,但不需要压缩文件。I have more than 2000 JS files in my web project to be formatted. I know that Google closure compiler is good at doing so and actually I am using it to write a tool for the whole JS files' formatting. My requirement is that the formatted JS files will replace the original ones at the same place.
I wrote a Java program to look up each JS file in the web project, when there is a file found, A thread will be responsible for executing the command
java -jar compiler.jar --js C:/project/xyz/abc.js --js_output_file C:/project/xyz/abc.js`And the original JS file(abc.js) will be formatted.
But I find that this way is not so efficient. The thing is I am using ExecutorService to run the threads and each thread takes around 10 seconds to do the formatting for a file. So you can imagine how long it takes to finish more than 2000 files.
Below is the code snippet.
ExecutorService executor = Executors.newFixedThreadPool(10); // ... for(File jsFile : root.listFiles()) { Runnable formatThread = new FormatThread(jsFilePath.getAbsolutePath()); //execute command "java -jar compiler.jar in run(), handled by ProcessBuilder executor.execute(formatThread); }I have tried increasing the thread pool size, but CPU and memory are soon consumed highly after the program started.
My questions are
What is the efficient way to format such a large number of files by application written in Java? Is the usage of ExecutorService in my program correct and suitable for my use case? Any other Java API can format Javascript files much quickly? Actually what I need is simply remove the empty lines and user comments but no need to compress the files.最满意答案
通过命令行启动所有这些任务会产生巨大的开销,因为它还需要启动一个新的jvm。
您可以从jar清单表单java代码运行主类的main方法(afaik com.google.javascript.jscomp.CommandLineRunner ):
for(File jsFile : root.listFiles()) { Runnable formatThread = () -> com.google.javascript.jscomp.CommandLineRunner.main(new String[] {"--js", jsFilePath.getAbsolutePath(), "--js_output_file", jsFilePath.getAbsolutePath()})); executor.execute(formatThread); }甚至可能有一种更有效的方式来调用API ......
编辑:
最好以不同的方式调用API。 例如
CompilerOptions options = new CompilerOptions(); CompilationLevel.ADVANCED_OPTIMIZATIONS.setOptionsForCompilationLevel(options); options.setCheckGlobalThisLevel(CheckLevel.OFF); options.setOutputCharset("utf-8"); com.google.javascript.jscomp.Compiler compiler = new com.google.javascript.jscomp.Compiler(System.err); compiler.disableThreads(); compiler.compile(SourceFile.fromFile(externsFile), SourceFile.fromFile(jsFile), options); String result = compiler.toSource(); // TODO: write result to fileStarting all those tasks via command line is producing a huge overhead, since it also needs to start up a new jvm.
You can run the main method of the main class (afaik com.google.javascript.jscomp.CommandLineRunner) from the jar manifest form java code though:
for(File jsFile : root.listFiles()) { Runnable formatThread = () -> com.google.javascript.jscomp.CommandLineRunner.main(new String[] {"--js", jsFilePath.getAbsolutePath(), "--js_output_file", jsFilePath.getAbsolutePath()})); executor.execute(formatThread); }There may even be a more efficient way of invoking the API...
Edit:
The API is better invoked in a different way. e.g.
CompilerOptions options = new CompilerOptions(); CompilationLevel.ADVANCED_OPTIMIZATIONS.setOptionsForCompilationLevel(options); options.setCheckGlobalThisLevel(CheckLevel.OFF); options.setOutputCharset("utf-8"); com.google.javascript.jscomp.Compiler compiler = new com.google.javascript.jscomp.Compiler(System.err); compiler.disableThreads(); compiler.compile(SourceFile.fromFile(externsFile), SourceFile.fromFile(jsFile), options); String result = compiler.toSource(); // TODO: write result to file更多推荐
发布评论