2015-11-08 7 views
15

मेरे पास जावा प्रोग्राम (जेडीके 7u80 का उपयोग करके संकलित) है जो "जावास्क्रिप्ट" स्क्रिप्टइंजिन (जेएसआर -223) का व्यापक उपयोग करता है। मैंने देखा है कि जावा 7 रनटाइम पर्यावरण (जेआरई 7u80) की तुलना में जावा 8 रनटाइम पर्यावरण (जेआरई 8u65) के तहत निष्पादित होने पर मेरा प्रोग्राम बहुत धीमा चलता है।जावा 8 स्क्रिप्टइंजिन के साथ प्रमुख प्रदर्शन मुद्दे जावा की तुलना में 7

मैं एक साथ जावा 7 और जावा 8 के तहत एक ही विंडोज पीसी पर डाल दिया है निम्नलिखित SSCCE समस्या प्रदर्शित करने के लिए और फिर मार डाला यह:

import javax.script.*; 

public class SSCCE { 
    public SSCCE() { 
    ScriptEngineManager sem = new ScriptEngineManager(); 
    ScriptEngine js = sem.getEngineByName("JavaScript"); 
    long t = 0; 
    int i = 0; 

    String gJs = "function ip2long(ip) {"; 
    gJs += "var aIP = ip.split(\".\");"; 
    gJs += "return (aIP[0] * Math.pow(256, 3)) + (aIP[1] * Math.pow(256, 2)) + (aIP[2] * 256) + (aIP[3] * 1);"; 
    gJs += "}"; 
    gJs += "function long2ip(l) {"; 
    gJs += "if (!isNaN(l) && ((l >= 0) || (l <= Math.pow(2, 32)))) {"; 
    gJs += "return Math.floor(l/Math.pow(256, 3)) + \".\" +"; 
    gJs += "Math.floor((l % Math.pow(256, 3))/Math.pow(256, 2)) + \".\" +"; 
    gJs += "Math.floor(((l % Math.pow(256, 3)) % Math.pow(256, 2))/Math.pow(256, 1)) + \".\" +"; 
    gJs += "Math.floor((((l % Math.pow(256, 3)) % Math.pow(256, 2)) % Math.pow(256, 1))/Math.pow(256, 0));"; 
    gJs += "}"; 
    gJs += "return null;"; 
    gJs += "}"; 

    try { 
     js.eval(gJs); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 

    System.out.println("Warming Up..."); 

    t = System.nanoTime(); 

    for (i = 0; i < 4097; i++) { 
     try { 
     String sJs = "var ip = \"192.0.2.0\";"; 
     sJs += "var nip = long2ip(ip2long(ip, " + i + "));"; 
     js.eval(sJs); 
     } 
     catch (Exception e) { 
     e.printStackTrace(); 
     } 
    } 

    System.out.println("Starting..."); 

    t = System.nanoTime(); 

    for (i = 0; i < 4097; i++) { 
     try { 
     String sJs = "var ip = \"192.0.2.0\";"; 
     sJs += "var nip = long2ip(ip2long(ip, " + i + "));"; 
     js.eval(sJs); 
     } 
     catch (Exception e) { 
     e.printStackTrace(); 
     } 
    } 

    System.out.println("Elapsed Time: " + (System.nanoTime() - t)/1000000000.0f); 
    } 

    public static void main(String[] args) { 
    new SSCCE(); 
    } 
} 

जावास्क्रिप्ट एक समारोह जो करने के लिए एक आईपी पता धर्मान्तरित के होते हैं एक लंबा, एक संख्या जोड़ता है और फिर इसे एक आईपी पते पर वापस परिवर्तित करता है - यह 4096 बार दोहराया जाता है।

मैं जावा 7 और जावा 8 के बीच निम्न परिणाम देख रहा हूँ:

D:\Scripts>java7 SSCCE 
Warming Up... 
Starting... 
Elapsed Time: 0.5856594 

D:\Scripts>java8 SSCCE 
Warming Up... 
Starting... 
Elapsed Time: 4.6862915 

मैं जावा 8 के साथ जुड़े एक प्रदर्शन बग के रूप में यह ऊपर उठाने किया जाना चाहिए?

अद्यतन: यह सुनिश्चित करने के लिए एक गर्म अप चरण शामिल करने के लिए कि मेरे टाइम लूप से पहले सभी कोड पथ प्रारंभ किए गए हैं।

+2

मैं आपके परिणामों को पुन: उत्पन्न नहीं कर सकता, शायद इसलिए कि आपने एक गर्मजोशी चरण शामिल नहीं किया है। – Tunaki

+0

यह एक प्रश्न का डुप्लिकेट कैसा है जो जावा 7 और जावा 8 के बीच प्रदर्शन अंतर के बारे में कुछ भी नहीं बताता है? यह एक पोस्ट है जो बताता है कि माइक्रो-बेंचमार्क कैसे करें। अगर मैं सही ढंग से उस पोस्ट को पढ़ता हूं तो मुझे दो बार लूप करना चाहिए, लेकिन दूसरी बार इसे केवल समय देना चाहिए? – chrixm

+2

मेरा सुझाव है कि आप सही बेंचमार्क करने के लिए जेएमएच देखें। यह एक पुस्तकालय है जो स्वचालित रूप से एक वार्मअप चरण शामिल करेगा और गलत चीज़ को मापने से बचें। जो अंतर आप प्राप्त कर रहे हैं वह सिर्फ इसलिए हो सकता है क्योंकि नाहसॉर्न राइनो से अधिक भार लेता है। – Tunaki

उत्तर

3

जावा 8 जावास्क्रिप्ट इंजन में सुधार करता है, यदि आप प्रत्येक बार स्रोत कोड का पुनर्मूल्यांकन न करने के लिए संकलित संकलितस्क्रिप्ट प्रकार का उपयोग करते हैं। Eval विधि के साथ, जेडीके 8 में इस्तेमाल किया गया हैशॉर्म इंजन जेडीके 7 में इस्तेमाल राइनो से धीमा है, लेकिन अधिक सुरक्षित है।

एक स्ट्रिंग बनाम एक StringBuffer पसंद करते हैं, और Math.pow (2, 32) और Math.pow के लिए स्थिरांक के उपयोग (256, 3) को महत्व देता है, तो आप गति के लिए की तलाश में ...

तुम्हारा

+0

सभी टिप्पणियों और सुझावों के लिए धन्यवाद। मैंने दो prong दृष्टिकोण अपनाया है - पहला है एक बार स्क्रिप्ट को 'eval' करें और फिर जहां संभव हो 'invokeFunction' का उपयोग करें। उन क्षेत्रों में जहां यह संभव नहीं है क्योंकि यह उपयोगकर्ता जावास्क्रिप्ट प्रदान करता है (मेरा उपयोग केस एक टेम्पलेटिंग टूल है जहां उपयोगकर्ता ब्लॉक में जावास्क्रिप्ट का उपयोग कर सकते हैं), मैंने अपनाया है समांतर में टेम्पलेट्स को संसाधित करने के लिए एक्स थ्रेड के एक निश्चित थ्रेड पूल का उपयोग करके एक थ्रेडिंग मॉड्यूल। – chrixm

संबंधित मुद्दे