如何测量Java中进程执行代码的执行时间?
How to measure execution time of the code executed by process in Java?
我正在做一个编程在线评判项目,比如 HackerRank、Codeforces 等...
我有线程池,当请求到来时,Web 服务从线程池中获取一个线程,该线程使用 ProcessBuilder 编译代码(直到这里一切正常),编译后,该线程通过使用开始执行部分又是一个新的 Processbuilder。但是我的 "time limit exceed" 部分计算不正确。当请求数量增加时,我认为该过程运行缓慢,因此任何基本代码都会超时。如何测量进程执行的代码的执行时间?(测量不应受请求数量的影响)
编辑:我的进程应该等待 process.But 的用户时间,我不知道该怎么做。
我的执行代码在这里:
package org.anil.CodeChecker.process;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.concurrent.TimeUnit;
import org.anil.CodeChecker.model.ExecutorModel;
public class Executor {
private ProcessBuilder p;
private String path;
private String input;
private String output;
private String lang;
private long timeInMillis;
public Executor(String path,String input, String output,String lang,long timeInMillis ){
this.path = path;
this.input = input;
this.output = output;
this.lang = lang;
this.timeInMillis = timeInMillis;
}
public ExecutorModel execute(){
ExecutorModel model = new ExecutorModel();
System.out.println("Code started executing");
if(lang.equals("java")){
p = new ProcessBuilder("java","Solution");
}
else if(lang.equals("c")){
p = new ProcessBuilder("./a.out");
}
else if(lang.equals("c++")){
p = new ProcessBuilder("./a.out");
}
else{
System.out.println("language is not correct...");
p = null;
}
p.directory(new File(path));
p.redirectErrorStream(true);
// System.out.println("Current directory "+System.getProperty("user.dir"));
try{
Process pp = p.start();
BufferedReader reader =
new BufferedReader(new InputStreamReader(pp.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
/*process e input veriliyor bu kısımda */
OutputStream outputstream = pp.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputstream));
writer.write(input);
writer.flush();
writer.close();
if(!pp.waitFor(timeInMillis, TimeUnit.MILLISECONDS)){
System.out.println("TİME LİMİT EXCEED !!!! ");
model.setTimelimit(true);
return model;
}
else{
model.setTimelimit(false);
int exitCode = pp.exitValue();
System.out.println("Exit Value = "+pp.exitValue());
if(exitCode != 0){
System.out.println("RUNTIME ERROR !!!!!!");
model.setSuccess(false);
model.setRuntimeerror(true);
return model;
}
}
while ( (line = reader.readLine()) != null) {
builder.append(line);
//builder.append(System.getProperty("line.separator"));
}
String result = builder.toString();
System.out.println(" output:"+result+" input:"+input);
if(result.charAt(result.length()-1) == ' ')
result = result.substring(0, result.length()-1);
if(result.equals(output)){
model.setSuccess(true);
model.setWronganswer(false);
System.out.println("OUTPUT (SUCCESS) = "+result);
return model;
}
else{
model.setSuccess(false);
model.setWronganswer(true);
System.out.println("OUTPUTTT (FAIL) = "+result);
return model;
}
}catch(IOException ioe){
System.err.println("in execute() "+ioe);
}catch (InterruptedException ex){
System.err.println(ex);
}
System.out.println("CODE EXECUTION FINISHED !");
return model;
}
}
你试过吗:
public long getCpuTime() {
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
return bean.isCurrentThreadCpuTimeSupported() ? bean.getCurrentThreadCpuTime() : 0L;
}
在启动进程的线程启动时使用该方法,然后在该线程结束时再次使用它(因为据我所知,它也会结束进程),然后检查增量(又名差异,最后一次使用方法减去第一次使用),以获取该线程已经运行了多长时间的时间 运行,从而间接获取该进程花费的时间?
如果我没记错的话,这种方法比使用 System.currentTimeMillis() 更好,因为它计算了给定特定线程的 cpu 时间,不包括其他线程使用的时间作为后台的其他系统进程 运行。
我正在做一个编程在线评判项目,比如 HackerRank、Codeforces 等...
我有线程池,当请求到来时,Web 服务从线程池中获取一个线程,该线程使用 ProcessBuilder 编译代码(直到这里一切正常),编译后,该线程通过使用开始执行部分又是一个新的 Processbuilder。但是我的 "time limit exceed" 部分计算不正确。当请求数量增加时,我认为该过程运行缓慢,因此任何基本代码都会超时。如何测量进程执行的代码的执行时间?(测量不应受请求数量的影响)
编辑:我的进程应该等待 process.But 的用户时间,我不知道该怎么做。
我的执行代码在这里:
package org.anil.CodeChecker.process;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.concurrent.TimeUnit;
import org.anil.CodeChecker.model.ExecutorModel;
public class Executor {
private ProcessBuilder p;
private String path;
private String input;
private String output;
private String lang;
private long timeInMillis;
public Executor(String path,String input, String output,String lang,long timeInMillis ){
this.path = path;
this.input = input;
this.output = output;
this.lang = lang;
this.timeInMillis = timeInMillis;
}
public ExecutorModel execute(){
ExecutorModel model = new ExecutorModel();
System.out.println("Code started executing");
if(lang.equals("java")){
p = new ProcessBuilder("java","Solution");
}
else if(lang.equals("c")){
p = new ProcessBuilder("./a.out");
}
else if(lang.equals("c++")){
p = new ProcessBuilder("./a.out");
}
else{
System.out.println("language is not correct...");
p = null;
}
p.directory(new File(path));
p.redirectErrorStream(true);
// System.out.println("Current directory "+System.getProperty("user.dir"));
try{
Process pp = p.start();
BufferedReader reader =
new BufferedReader(new InputStreamReader(pp.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
/*process e input veriliyor bu kısımda */
OutputStream outputstream = pp.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputstream));
writer.write(input);
writer.flush();
writer.close();
if(!pp.waitFor(timeInMillis, TimeUnit.MILLISECONDS)){
System.out.println("TİME LİMİT EXCEED !!!! ");
model.setTimelimit(true);
return model;
}
else{
model.setTimelimit(false);
int exitCode = pp.exitValue();
System.out.println("Exit Value = "+pp.exitValue());
if(exitCode != 0){
System.out.println("RUNTIME ERROR !!!!!!");
model.setSuccess(false);
model.setRuntimeerror(true);
return model;
}
}
while ( (line = reader.readLine()) != null) {
builder.append(line);
//builder.append(System.getProperty("line.separator"));
}
String result = builder.toString();
System.out.println(" output:"+result+" input:"+input);
if(result.charAt(result.length()-1) == ' ')
result = result.substring(0, result.length()-1);
if(result.equals(output)){
model.setSuccess(true);
model.setWronganswer(false);
System.out.println("OUTPUT (SUCCESS) = "+result);
return model;
}
else{
model.setSuccess(false);
model.setWronganswer(true);
System.out.println("OUTPUTTT (FAIL) = "+result);
return model;
}
}catch(IOException ioe){
System.err.println("in execute() "+ioe);
}catch (InterruptedException ex){
System.err.println(ex);
}
System.out.println("CODE EXECUTION FINISHED !");
return model;
}
}
你试过吗:
public long getCpuTime() {
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
return bean.isCurrentThreadCpuTimeSupported() ? bean.getCurrentThreadCpuTime() : 0L;
}
在启动进程的线程启动时使用该方法,然后在该线程结束时再次使用它(因为据我所知,它也会结束进程),然后检查增量(又名差异,最后一次使用方法减去第一次使用),以获取该线程已经运行了多长时间的时间 运行,从而间接获取该进程花费的时间?
如果我没记错的话,这种方法比使用 System.currentTimeMillis() 更好,因为它计算了给定特定线程的 cpu 时间,不包括其他线程使用的时间作为后台的其他系统进程 运行。