जेवीएम अभी भी टेल-कॉल ऑप्टिमाइज़ेशन का समर्थन क्यों नहीं करता है?


95

जेवीएम-रोकथाम-टेल-कॉल-अनुकूलन के दो साल बाद , वहाँ एक प्रोटोटाइप कार्यान्वयन लगता है और एमएलवीएम ने कुछ समय के लिए "प्रोटो 80%" के रूप में सुविधा को सूचीबद्ध किया है।

सपोर्टिंग टेल कॉल में सन / ओरेकल की तरफ से कोई सक्रिय रुचि नहीं है या क्या यह है कि टेल कॉल "[...] जेवीएम में उल्लिखित हर सुविधा प्राथमिकता सूची [...] पर दूसरे स्थान पर आने के लिए है। भाषा शिखर सम्मेलन ?

मुझे वास्तव में दिलचस्पी होगी अगर किसी ने एक एमएलवीएम बिल्ड का परीक्षण किया है और यह कुछ छापों को साझा कर सकता है कि यह कितना अच्छा काम करता है (यदि बिल्कुल भी)।

अपडेट: ध्यान दें कि कुछ वीएम जैसे एवियन बिना किसी समस्या के उचित टेल-कॉल का समर्थन करते हैं।


14
ओरेकल से सूर्य के लोगों के पलायन की सूचना के साथ, मैं यह उम्मीद नहीं करूंगा कि कोई भी मौजूदा परियोजना तब तक जारी रहेगी जब तक कि ओरेकल से स्पष्ट रूप से ऐसा नहीं कहा जाता :(
थोरबजर्न रावन एंडरसन

16
ध्यान दें कि आपका स्वीकृत उत्तर पूरी तरह से गलत है। टेल कॉल ऑप्टिमाइज़ेशन और OOP के बीच कोई मौलिक संघर्ष नहीं है और निश्चित रूप से, OCaml और F # जैसी कई भाषाओं में OOP और TCO दोनों हैं।
JD

2
खैर, OCaml और F # OOP भाषाओं को कॉल करना पहली जगह में एक बुरा मजाक है। लेकिन हां, OOP और TCO आम तौर पर ज्यादा नहीं हैं, सिवाय इस तथ्य के कि रनटाइम को जांचना है कि जिस तरीके से ऑप्टिमाइज़ किया जा रहा है वह कहीं और ओवरराइड / सबक्लेस्ड तो नहीं है।
सामाजिक

5
+1 C बैकग्राउंड से आने पर, मैंने हमेशा यह माना कि TCO किसी भी आधुनिक JVM में दिया गया था। यह वास्तव में जांचने के लिए मेरे साथ कभी नहीं हुआ और जब मैंने परिणाम देखा तो आश्चर्य हुआ ...
thkala

2
@soc: "इस तथ्य को छोड़कर कि रनटाइम को यह जांचना है कि अनुकूलित किया जा रहा तरीका कहीं ओवरराइड / सबक्लेस्ड नहीं है"। आपका "तथ्य" पूर्ण बकवास है।
जेडी

जवाबों:


32

जावा कोड का निदान करना: अपने जावा कोड ( Alt ) के प्रदर्शन में सुधार करना बताता है कि जेवीएम टेल-कॉल ऑप्टिमाइज़ेशन का समर्थन क्यों नहीं करता है।

हालाँकि यह अच्छी तरह से जाना जाता है कि टेल-रिकर्सिव फ़ंक्शन को एक साधारण लूप में स्वचालित रूप से कैसे बदलना है, जावा विनिर्देशन को इस परिवर्तन की आवश्यकता नहीं है। संभवतः, एक कारण यह आवश्यकता नहीं है कि, सामान्य रूप से, वस्तु-उन्मुख भाषा में परिवर्तन को सांख्यिकीय रूप से नहीं किया जा सकता है। इसके बजाय, पूंछ-पुनरावर्ती फ़ंक्शन से सरल लूप में परिवर्तन गतिशील रूप से एक जेआईटी संकलक द्वारा किया जाना चाहिए।

यह तब जावा कोड का एक उदाहरण देता है जो रूपांतरित नहीं होगा।

इसलिए, लिस्टिंग 3 शो में उदाहरण के रूप में, हम भाषा के शब्दार्थ को संरक्षित करते हुए जावा कोड पर पूंछ पुनरावृत्ति के परिवर्तन के लिए स्थिर संकलक से अपेक्षा नहीं कर सकते। इसके बजाय, हमें जेआईटी द्वारा गतिशील संकलन पर भरोसा करना चाहिए। JVM के आधार पर, JIT ऐसा कर भी सकता है और नहीं भी।

तब यह एक परीक्षण देता है जिसका उपयोग आप यह पता लगाने के लिए कर सकते हैं कि आपका JIT ऐसा करता है या नहीं।

स्वाभाविक रूप से, चूंकि यह एक आईबीएम पेपर है, इसमें एक प्लग शामिल है:

मैंने इस कार्यक्रम को जावा एसडीके के एक जोड़े के साथ चलाया, और परिणाम आश्चर्यजनक थे। संस्करण 1.3 के लिए सन के हॉटस्पॉट जेवीएम पर चलने से पता चलता है कि हॉटस्पॉट परिवर्तन का प्रदर्शन नहीं करता है। डिफ़ॉल्ट सेटिंग्स पर, स्टैक स्पेस मेरी मशीन पर एक सेकंड से भी कम समय में समाप्त हो जाता है। दूसरी ओर, समस्या के बिना संस्करण 1.3 purrs के लिए IBM का JVM, यह दर्शाता है कि यह इस तरह से कोड को रूपांतरित करता है।


62
एफडब्ल्यूआईडब्ल्यू, टेल कॉल सिर्फ आत्म-पुनरावर्ती कार्यों के बारे में नहीं हैं जैसा कि उनका तात्पर्य है। टेल कॉल किसी भी फ़ंक्शन कॉल हैं जो पूंछ की स्थिति में दिखाई देती हैं। उन्हें स्वयं को कॉल करने की आवश्यकता नहीं है और उन्हें सांख्यिकीय रूप से ज्ञात स्थानों पर कॉल करने की आवश्यकता नहीं है (जैसे वे आभासी विधि कॉल हो सकते हैं)। वह समस्या का वर्णन करता है जो एक गैर-मुद्दा है यदि पूंछ कॉल अनुकूलन सामान्य मामले में ठीक से किया जाता है और, परिणामस्वरूप, उसका उदाहरण पूरी तरह से ऑब्जेक्ट ओरिएंटेड भाषाओं में काम करता है जो पूंछ कॉल (जैसे OCaml और F #) का समर्थन करते हैं।
जद

3
"गतिशील रूप से एक जेआईटी कंपाइलर द्वारा किया जाना चाहिए" जिसका अर्थ है कि यह जावा कंपाइलर के बजाय जेवीएम द्वारा ही किया जाना चाहिए। लेकिन ओपी जेवीएम के बारे में पूछ रहा है।
राएडवल्ड

11
"सामान्य तौर पर, परिवर्तन को वस्तु-उन्मुख भाषा में वैधानिक रूप से नहीं बनाया जा सकता है।" यह निश्चित रूप से एक उद्धरण है, लेकिन हर बार जब मैं इस तरह के बहाने देखता हूं तो मैं संख्याओं के बारे में पूछना चाहता हूं - क्योंकि मुझे आश्चर्य नहीं होगा कि अगर अधिकांश मामलों में यह संकलन समय पर स्थापित किया जा सकता है।
ग्रीनल्डमैन

5
उद्धृत लेख का लिंक अब टूट गया है, हालाँकि Google के पास यह कैश नहीं है। इससे भी महत्वपूर्ण बात, लेखक का तर्क दोषपूर्ण है। दिए गए उदाहरण को टेल-कॉल ऑप्टिमाइज़ किया जा सकता है, स्थैतिक और सिर्फ गतिशील संकलन का उपयोग नहीं किया जा सकता है , यदि केवल संकलक ने यह instanceofदेखने के लिए एक चेक डाला कि thisक्या कोई Exampleऑब्जेक्ट है (उपवर्ग के बजाय Example)।
एलेक्स डी।


30

जावा में TCO को लागू नहीं करने के लिए (और इसे मुश्किल के रूप में देखा जा रहा है) एक कारण यह है कि JVM में अनुमति मॉडल स्टैक-सेंसिटिव है और इस प्रकार टेल-कॉल को सुरक्षा पहलुओं को संभालना चाहिए।

मेरा मानना ​​है कि यह कॉल्स और फेलिसन [1] [2] द्वारा बाधा नहीं बनने के लिए दिखाया गया था और मुझे पूरा यकीन है कि एमएलवीएम पैच का उल्लेख इस प्रश्न से भी है।

मुझे एहसास है कि यह आपके सवाल का जवाब नहीं देता है; बस दिलचस्प जानकारी जोड़ना।

  1. http://www.ccs.neu.edu/scheme/pubs/esop2003-cf.pdf
  2. http://www.ccs.neu.edu/scheme/pubs/cf-toplas04.pdf

1
+1। ब्रायन गोएट्ज youtube.com/watch?v=2y5Pv4yN0b0&t=3739
mcoolive

15

शायद आप यह पहले से ही जानते हैं, लेकिन यह सुविधा उतनी तुच्छ नहीं है क्योंकि यह ध्वनि हो सकती है क्योंकि जावा भाषा वास्तव में प्रोग्रामर को स्टैक ट्रेस को उजागर करती है।

निम्नलिखित कार्यक्रम पर विचार करें:

public class Test {

    public static String f() {
        String s = Math.random() > .5 ? f() : g();
        return s;
    }

    public static String g() {
        if (Math.random() > .9) {
            StackTraceElement[] ste = new Throwable().getStackTrace();
            return ste[ste.length / 2].getMethodName();
        }
        return f();
    }

    public static void main(String[] args) {
        System.out.println(f());
    }
}

भले ही इसमें "टेल-कॉल" हो लेकिन इसे अनुकूलित नहीं किया जा सकता है। (यह तो है अनुकूलित किया है, यह अभी भी कार्यक्रम यह पर निर्भर करता है के शब्दों के बाद से पूरे कॉल-स्टैक की किताब रखने की आवश्यकता है।)

मूल रूप से, इसका मतलब यह है कि पिछड़े संगत होते हुए भी इसका समर्थन करना कठिन है।


17
आपके विचार में गलती पाई गई: "कार्यक्रम के शब्दार्थ इस पर निर्भर होने के बाद से पूरे कॉल-स्टैक के बुक-कीपिंग की आवश्यकता है"। :-) यह नए "दबाए गए अपवाद" की तरह है। ऐसी बातों पर भरोसा करने वाले कार्यक्रम टूटने के लिए बाध्य हैं। मेरी राय में कार्यक्रम का व्यवहार बिल्कुल सही है: स्टैक फ्रेम को दूर फेंकना टेल कॉल की बात है।
सामाजिक

4
@ मार्को, लेकिन बस किसी भी विधि के बारे में एक अपवाद फेंक सकता है, जिसमें से पूरी कॉल-स्टैक उपलब्ध होने के लिए बाध्य है, है ना? इसके अलावा, आप पहले से तय नहीं कर सकते हैं कि gइस मामले में कौन से तरीके अप्रत्यक्ष रूप से कहेंगे ... उदाहरण के लिए बहुरूपता और प्रतिबिंब के बारे में सोचें।
एरियोबे

2
यह जावा 7 में एआरएम के अतिरिक्त के कारण एक साइड-इफेक्ट है। यह एक उदाहरण है कि आप ऐसी चीजों पर भरोसा नहीं कर सकते हैं जो आपने ऊपर दिखाया था।
सामाजिक

6
"तथ्य यह है कि भाषा कॉल-स्टैक को उजागर करती है, इसे लागू करना कठिन हो जाता है": क्या भाषा की आवश्यकता है कि स्टैक-ट्रेस getStackTrace()एक विधि से लौटा है x()जो स्रोत कोड शो को एक विधि से y()भी दिखाता है x()जिसे कहा जाता था y()? अगर कुछ स्वतंत्रता है तो कोई वास्तविक मुद्दा नहीं है।
राएडवल्ड

8
यह केवल एक एकल विधि के क्रम को खराब करने का मामला है, "आपको सभी स्टैक फ़्रेम देता है" से "आपको सभी सक्रिय स्टैकफ्रेम देता है, जो टेल कॉल द्वारा obsoleted वाले लोगों को छोड़ देता है"। इसके अलावा, कोई भी इसे कमांड लाइन स्विच या सिस्टम प्रॉपर्टी बना सकता है चाहे टेल-कॉल सम्मानित किया गया हो।
इंगो

12

जावा कम से कम कार्यात्मक भाषा है जिसे आप संभवतः कल्पना कर सकते हैं (अच्छी तरह से, ठीक है, शायद नहीं !) लेकिन यह जेएवीएम भाषाओं के लिए एक महान लाभ होगा, जैसे कि स्काला , जो हैं।

मेरी टिप्पणियों का मानना ​​है कि जेवीएम को अन्य भाषाओं के लिए एक मंच बनाना कभी भी सूर्य के लिए प्राथमिकता सूची में सबसे ऊपर नहीं लगता है और मुझे लगता है, अब ओरेकल के लिए।


16
@ Thorbjørn - मैंने भविष्यवाणी करने के लिए एक कार्यक्रम लिखा था कि क्या कोई भी कार्यक्रम समय की एक सीमित मात्रा में रुकेगा। यह मुझे उम्र ले गया !
oxbow_lakes

3
मेरे द्वारा उपयोग किए गए पहले BASIC में फ़ंक्शंस नहीं थे, बल्कि GOSUB और RETURN थे। मुझे नहीं लगता कि LOLCODE बहुत कार्यात्मक है, या तो (और आप इसे दो अर्थों में ले सकते हैं)।
डेविड थॉर्नले

1
@ डेविड, कार्यात्मक! = कार्य हैं।
थोरबजर्न रेवन एंडरसन

2
@ Thorbjørn रावन एंडरसन: नहीं, लेकिन यह एक शर्त है, क्या आप नहीं कहेंगे?
डेविड थॉर्नले

3
"जेवीएम को अन्य भाषाओं के लिए एक मंच बनाना कभी भी सूर्य के लिए प्राथमिकता सूची में सबसे ऊपर नहीं लगता है"। उन्होंने कार्यात्मक भाषाओं के लिए जेवीएम को गतिशील भाषाओं के लिए एक मंच बनाने में बहुत अधिक प्रयास किया।
जेडी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.