2013-08-06 3 views
2

PHP에서 proc_open을 사용하여 Java 응용 프로그램을 호출하고 처리 할 텍스트를 전달하고 출력 텍스트를 읽습니다. Java 실행 시간이 꽤 길어서 그 이유는 대부분 읽기에 시간이 걸린다는 것을 알게되었습니다. php 또는 java의 잘못인지 여부는 확실하지 않습니다.php proc_open 입력을 java에 전달하는 중

내 PHP 코드 :

$process_cmd = "java -Dfile.encoding=UTF-8 -jar test.jar"; 

$env = NULL; 

$options = ["bypass_shell" => true]; 
$cwd = NULL; 
$descriptorspec = [ 
    0 => ["pipe", "r"],  //stdin is a pipe that the child will read from 
    1 => ["pipe", "w"],  //stdout is a pipe that the child will write to 
    2 => ["file", "java.error", "a"] 
]; 

$process = proc_open($process_cmd, $descriptorspec, $pipes, $cwd, $env, $options); 

if (is_resource($process)) { 

    //feeding text to java 
    fwrite($pipes[0], $input); 
    fclose($pipes[0]); 

    //reading output text from java 
    $output = stream_get_contents($pipes[1]); 
    fclose($pipes[1]); 

    $return_value = proc_close($process); 

} 

내 자바 코드 : 나는 (독립형 파일로 크기가 ~ 200킬로바이트) 3800 개 라인의 자바 html 파일로 전달하고 있습니다

public static void main(String[] args) throws Exception { 

    long start; 
    long end; 

    start = System.currentTimeMillis(); 

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
    String in; 
    String input = ""; 
    br = new BufferedReader(new InputStreamReader(System.in)); 
    while ((in = br.readLine()) != null) { 
     input += in + "\n"; 
    } 

    end = System.currentTimeMillis(); 
    log("Input: " + Long.toString(end - start) + " ms"); 


    start = System.currentTimeMillis(); 

    org.jsoup.nodes.Document doc = Jsoup.parse(input); 

    end = System.currentTimeMillis(); 
    log("Parser: " + Long.toString(end - start) + " ms"); 


    start = System.currentTimeMillis(); 

    System.out.print(doc); 

    end = System.currentTimeMillis(); 
    log("Output: " + Long.toString(end - start) + " ms"); 

} 

. 이 로그 파일의 실행 시간을 부러 : 왜 입력이 출력보다 100 배 더 오래 걸릴 않습니다

Input: 1169 ms 
Parser: 98 ms 
Output: 12 ms 

내 질문이 무엇입니까? 빨리 할 수있는 방법이 있습니까?

+0

의 권장 사항을 고려 ** 번 ** :'새의 BufferedReader (새로운 InputStreamReader (System.in))'- 고통 스러울 수 . 물론'StringBuilder' 대신'String + ='을 쓰면 속도가 느려집니다. –

답변

0

자바 프로그램에 읽기 블록을 검사 : (대신 String+=를 사용하는) 데이터를 CONCAT하는 StringBuilder를 사용해보십시오 :

String in; 
StringBuilder input = new StringBulider(); 
br = new BufferedReader(new InputStreamReader(System.in)); 
while ((in = br.readLine()) != null) { 
    input.append(in + "\n"); 
} 

자세한 사항은 여기에 포함된다 : Why using StringBuilder explicitly


일반적으로 말하자면, 애플리케이션 서버 (또는 간단한 소켓 기반 서버)를 사용하여 더 빠르게 실행하려면 영구적으로 실행되는 JVM을 사용하는 것이 좋습니다. JVM을 시작할 때 항상 약간의 오버 헤드가 있으며 그 위에 JIT가 코드를 최적화하는 데 약간의 시간이 필요합니다. 이 노력은 JVM이 종료 된 후에 없어집니다.

PHP 프로그램의 경우 : 셸에서 Java 프로그램을 먹이십시오. cat을 사용하여 데이터를 파이프하십시오 (Linux와 같은 UNIX 시스템에서). 또는 Java 프로그램을 재 작성하여 파일에 대한 명령 행 매개 변수를 채택 할 수도 있습니다. 그런 다음 PHP 코드가 데이터를 충분히 빠르게 파이프하는지 판단 할 수 있습니다. 자바 프로그램으로

: 성능 분석을 할 경우, 당신은이 How do I write a correct micro-benchmark in Java

+0

답해 주셔서 감사합니다. 그러나 JVM이 이미 실행 된 후에 측정 된 실행 시간은 애플리케이션 내부에 있으므로 내 질문과 관련이 없습니다. 나는 "데이터를 파이프하기 위해 고양이를 사용하십시오"라는 것이 무슨 뜻인지 잘 모르겠습니다. Windows에서 개발 중이지만 프로덕션 서버는 Linux입니다. 필자는 파이프를 사용하여 파일 쓰기 및 읽기 오버 헤드를 줄였습니다. 이전 질문에 대한 대답이었습니다. PHP와 java 간의 가장 빠른 통신 방법은 무엇입니까? – Caballero

+0

측정은 JVM이 시작된 후에 수행되지만 JIT는 여전히 역할을 수행 할 수 있습니다. 테스트 케이스를 설정하는 동안 나는 StringBuilder가 없다는 사실을 발견했다. 따라서 자바 측에서이를 해결해야한다. – Beryllium

+0

감사합니다. StringBuilder 메서드는 입력 시간을 5ms로 줄였습니다. 이거 야. – Caballero