2014-02-20 61 views
3

我需要一些幫助,從c + +代碼的外部程序調用。C++:重複調用系統()

我不得不從我的程序中調用javap.exe(來自JDK包)多次(可能超過100次),但是調用system("javap.exe some_parameters")的速度非常慢。這對一組參數非常有用,但重複調用system()是不可接受的。我認爲這只是因爲訪問硬盤和應用程序運行的成本(但我不確定)。

我可以做些什麼來提高性能?我可以「將javap.exe保存在RAM中」並將其稱爲「直接」。 或者可能有人知道如何獲得java類描述和方法簽名而沒有javap.exe

+2

是否可以選擇擁有* persistent * Java實例,並通過JNI調用/回調進行通信? (這當然可以這樣做,問題是如果它可以被你接受,或者你每次需要*一個完全不同的Java實例)。 – DevSolar

+0

謝謝,我會試一試。我只是沒有太多的Java經驗。 – Dmitry

回答

6

Java虛擬機開始運行起來並不便宜,而且很可能它的初始化耗盡了大部分時間。幸運的是,javap的功能可直接通過Java代碼獲得。我建議你編寫一個小型的Java應用程序,它類似於javap,只需一次調用就可以完成,否則你將需要數千個應用程序。 (雖然...也許你已經可以只使用一個?javap的採取多類文件,畢竟...)

-1

調用system()是容易的,但效率非常低,主要是因爲你不只是啓動任何程序你指定。相反,您正在啓動一個進程(一個shell),並且該shell將檢查您的參數並啓動第二個進程。

如果您所使用的系統支持fork()exec*(),那麼您將改爲使用它們來提高性能。作爲一個僞代碼示例,請考慮:

void replace_system(const char *command) 
{ 
    pid_t child = fork(); 
    if (child < 0) { 
     perror("fork:"); 
     return; 
    } 

    if (child) { 
     /* this is the parent, wait for the child to finish */ 
     while (waitpid(child, &status, options) <= 0); 
     return; 
    } 

    /* this is the new process */ 
    exec*(...); 
    perror("failed to start the child"); 
    exit(-1); 
} 

根據您希望如何排列參數選擇一個exec *函數。你需要將你的參數串分解成組件,並可能提供你喜歡的環境。一旦調用exec *函數,該函數將永遠不會返回(除非啓動您爲其定義的命令時出現錯誤)。

除了性能方面的考慮,使用它的另一個原因是,如果需要,它允許您修改孩子的標準路徑。例如,你可能對一個孩子的輸出感興趣;如果您將其stdout修改爲可供您使用的管道,則可以簡單地閱讀它打印的內容。調用標準popen()調用源代碼來查找此示例。

+0

同意'fork' /'exec'會比'system'更有效率。但是與所有的JVM設置相比,我懷疑通過shell的開銷不會超過整個運行時間的點數。 – Sneftel

+0

@Sneftel我同意(並已提高您的答案)。儘管在信噪比方面,JVM啓動時間是system()的噪聲的信號,OP表示他正在調用system()可能超過100次;這是很多放大的噪音。 – mah

+0

如果貴= 1000 *(大+小),你**忽略**小。在存在大量數據時,任何小的優化都是過早的。如果昂貴=大+巨大*(小),那麼小的優化可能並不成熟。在上面的例子中,你告訴OP在OP應該完全忽略這個問題(小的優化)時優化小。在存在大量存在的同時,任何努力都是浪費的(假設大的比小的大得多)。 – Yakk