दस चीजें आप कर सकते हैं GraalVM के साथ


अनुवादक से: GraalVM एक नई, दिलचस्प तकनीक है, लेकिन Habré पर इस पर कई लेख नहीं हैं जो कि Graal क्षमताओं के उदाहरण दिखा सकते हैं। नीचे दिया गया लेख ग्रेगलम क्या कर सकता है, इसकी एक सूची नहीं है, बल्कि एक छोटा मास्टर वर्ग भी है जो कि क्रिस सीटन और ओलेग शेल्लाव ओरेकल कोडेन 2018 में आयोजित किया गया है। लेखक के बाद, मैं आपसे लेख से उदाहरण बनाने की कोशिश करने का आग्रह करता हूं, यह वास्तव में है। दिलचस्प।


GraalVM में बहुत सारी अलग-अलग चीजें हैं, और अगर आपने यह नाम पहले सुना है, या यहां तक ​​कि रिपोर्टों को देखा है, तो अभी भी बहुत सी चीजें हैं जिनके बारे में आप अभी भी नहीं जानते हैं, लेकिन जो GraalVM कर सकते हैं। इस लेख में, हम विभिन्न विशेषताओं को देखेंगे जो GraalVM प्रदान करता है और दिखाता है कि आप उनके साथ क्या कर सकते हैं।


  1. जावा तेजी से निष्पादन
  2. जावा के लिए प्रारंभ समय और मेमोरी उपयोग में कमी
  3. जावास्क्रिप्ट, जावा, रूबी और आर का संयोजन
  4. प्लेटफ़ॉर्म-विशिष्ट भाषाओं में लिखे गए कार्यक्रमों का निष्पादन
  5. सभी प्रोग्रामिंग भाषाओं के लिए सामान्य उपकरण
  6. जेवीएम एप्लीकेशन सप्लीमेंट
  7. प्लेटफार्म आश्रित अनुप्रयोग
  8. प्लेटफ़ॉर्म-विशिष्ट लाइब्रेरी के रूप में जावा कोड
  9. डेटाबेस में कई प्रोग्रामिंग भाषाओं के लिए समर्थन
  10. GraalVM के लिए प्रोग्रामिंग भाषा बनाना

आप इस लेख में दिखाए गए हर काम को GraalVM 1.0.0 RC1 का उपयोग करके कर सकते हैं, जो कि GraalVM वेबसाइट के लिंक के माध्यम से उपलब्ध है। मैंने MacOS एंटरप्राइज एडिशन का उपयोग किया है, लेकिन यहां जो कोड लिखा गया है वह लिनक्स और ग्रेवालम कम्युनिटी एडिशन पर काम करेगा।


जब आप लेख पढ़ते हैं, तो उसमें वर्णित कार्यक्रमों को चलाएं! GitHub से कोड डाउनलोड किया जा सकता है


स्थापना


Http://graalvm.org/downloads से डाउनलोड करने के बाद , मैंने $PATH में GraalVM निष्पादक के लिए रास्ता जोड़ा। डिफ़ॉल्ट रूप से, यह जावा और जावास्क्रिप्ट निष्पादन के लिए समर्थन जोड़ता है।


 $ git clone https://github.com/chrisseaton/graalvm-ten-things.git $ cd foo $ tar -zxf graalvm-ee-1.0.0-rc1-macos-amd64.tar.gz # or graalvm-ee-1.0.0-rc1-linux-amd64.tar.gz on Linux $ export PATH=graalvm-1.0.0-rc1/Contents/Home/bin:$PATH # or PATH=graalvm-1.0.0-rc1/bin:$PATH on Linux 

GraalVM अंतर्निहित जावास्क्रिप्ट समर्थन के साथ आता है और इसमें एक पैकेज प्रबंधक होता है जिसे gu कहा जाता है जो जावा और जावास्क्रिप्ट के अलावा अन्य भाषाओं के लिए समर्थन स्थापित करने की क्षमता जोड़ता है। मैंने अतिरिक्त रूप से रूबी, पायथन और आर को स्थापित किया, वे GitHub से डाउनलोड किए गए हैं।


 $ gu install -c org.graalvm.ruby $ gu install -c org.graalvm.python $ gu install -c org.graalvm.R 

अब, यदि आप java या js कमांड निष्पादित करते हैं, तो आप इन इंजनों के GraalVM संस्करण देखेंगे।


 $ java -version java version "1.8.0_161" Java(TM) SE Runtime Environment (build 1.8.0_161-b12) GraalVM 1.0.0-rc1 (build 25.71-b01-internal-jvmci-0.42, mixed mode) $ js --version Graal JavaScript 1.0 (GraalVM 1.0.0-rc1) 

1. फास्ट जावा निष्पादन


GraalVM में "ग्रेगल" संकलक का नाम है। वह अकेले ही सब पर राज करने के लिए बनाया गया है ! इसका मतलब यह है कि यह एक संकलक कार्यान्वयन है जिसे एक पुस्तकालय के रूप में लिखा गया है जिसका उपयोग बहुत सारी अलग-अलग चीजों के लिए किया जा सकता है। उदाहरण के लिए, हम विभिन्न प्रोसेसर आर्किटेक्चर सहित विभिन्न प्रोग्रामिंग भाषाओं में लिखे गए कोड को संकलित करने के लिए ग्रेवाल का उपयोग आगे-के-समय और जस्ट-इन-टाइम दोनों को संकलित करने के लिए करते हैं।


ग्रेल का उपयोग करने का पहला और आसान तरीका यह है कि इसे जावा जेआईटी संकलक के रूप में उपयोग किया जाए।


एक उदाहरण के रूप में, हम एक प्रोग्राम का उपयोग करेंगे जो एक दस्तावेज़ में 10 सबसे सामान्य शब्दों का उत्पादन करता है। कार्यक्रम आधुनिक जावा भाषा की क्षमताओं का उपयोग करता है, जैसे कि स्ट्रीम और संग्रह।


 import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; public class TopTen { public static void main(String[] args) { Arrays.stream(args) .flatMap(TopTen::fileLines) .flatMap(line -> Arrays.stream(line.split("\\b"))) .map(word -> word.replaceAll("[^a-zA-Z]", "")) .filter(word -> word.length() > 0) .map(word -> word.toLowerCase()) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) .entrySet().stream() .sorted((a, b) -> -a.getValue().compareTo(b.getValue())) .limit(10) .forEach(e -> System.out.format("%s = %d%n", e.getKey(), e.getValue())); } private static Stream<String> fileLines(String path) { try { return Files.lines(Paths.get(path)); } catch (IOException e) { throw new RuntimeException(e); } } } 

GraalVM में javac संकलक शामिल है, लेकिन इस डेमो के लिए कोई अंतर नहीं है कि इसका उपयोग करना है या मानक संकलक का। इसलिए, यदि आप चाहें तो आप मानक javac कंपाइलर का उपयोग कर सकते हैं।


 $ javac TopTen.java 

यदि हम java कमांड चलाते हैं, जो कि ग्रेवालवीएम में शामिल है, तो ग्रैट जेआईटी कंपाइलर को स्वचालित रूप से उपयोग किया जाएगा - कोई अतिरिक्त चरणों की आवश्यकता नहीं है। मैं time कमांड का उपयोग उस time वास्तविक डेटा को प्राप्त करने के लिए करूंगा, जो कि प्रोग्राम को शुरू करने से लेकर अंत तक एक जटिल माइक्रोबेनमार्क को तैनात करने पर खर्च किया गया था। बड़ी मात्रा में इनपुट का उपयोग भी किया जाएगा ताकि यहां या वहां सेकंड के सहेजे गए जोड़े के बारे में कोई जानकारी न हो। large.txt फ़ाइल का आकार 150 एमबी है।


 $ make large.txt $ time java TopTen large.txt sed = 502701 ut = 392657 in = 377651 et = 352641 id = 317627 eu = 317627 eget = 302621 vel = 300120 a = 287615 sit = 282613 real 0m17.367s user 0m32.355s sys 0m1.456s 

जावा के लिए अधिकांश अन्य JIT कंपाइलरों की तरह, Graal को Java में लिखा जाता है, C ++ में नहीं। हमें लगता है कि यह हमें मौजूदा कंपाइलरों की तुलना में तेजी से सुधार करने की अनुमति देता है, नए शक्तिशाली अनुकूलन (जैसे, उदाहरण के लिए, आंशिक भागने विश्लेषण) को जोड़ना जो हॉटस्पॉट के लिए मानक जेआईटी कंपाइलर में उपलब्ध नहीं हैं।
और यह आपके जावा प्रोग्राम को बहुत तेज बना सकता है।


तुलना उद्देश्यों के लिए, ग्रेइट जेआईटी संकलक के बिना प्रोग्राम चलाने के लिए, मैं -XX:-UseJVMCICompiler उपयोग -XX:-UseJVMCICompiler । जेवीएमसीआई ग्रैल और जेवीएम के बीच का इंटरफेस है। आप एक मानक JVM पर उदाहरण भी चला सकते हैं और परिणामों की तुलना कर सकते हैं।


 $ time java -XX:-UseJVMCICompiler TopTen large.txt sed = 502701 ut = 392657 in = 377651 et = 352641 id = 317627 eu = 317627 eget = 302621 vel = 300120 a = 287615 sit = 282613 real 0m23.511s user 0m24.293s sys 0m0.579s 

इस परीक्षण से पता चलता है कि ग्रेगल हमारे जावा प्रोग्राम को मानक हॉटस्पॉट कंपाइलर के साथ इसे चलाने में लगभग तीन चौथाई समय चलाता है। जहां हम मानते हैं कि प्रतिशत की इकाइयों द्वारा उत्पादकता में सुधार एक महत्वपूर्ण उपलब्धि है, 25% एक बड़ी बात है।


ट्विटर आज एकमात्र ऐसी कंपनी है जो "लड़ाई" सर्वर पर ग्रेगल का उपयोग करती है , और वे कहते हैं कि असली पैसे बचाने के मामले में यह उनके लिए उचित है। ट्विटर ग्रैला का उपयोग स्काला में लिखे गए अनुप्रयोगों को निष्पादित करने के लिए करता है - ग्रेवल बायटेकोड के जेवीएम स्तर पर काम करता है, अर्थात। किसी भी JVM भाषा पर लागू होता है।


यह GraalVM के लिए पहला उपयोग मामला है - बस अपने मौजूदा जावा अनुप्रयोगों के लिए बेहतर संस्करण के साथ JIT संकलक की जगह।


2. जावा के लिए प्रारंभ समय और मेमोरी उपयोग में कमी


लंबे समय से चल रही प्रक्रियाओं और पीक लोड के साथ काम करते समय जावा प्लेटफॉर्म की ताकतें विशेष रूप से स्पष्ट हैं। इसके विपरीत अल्पकालिक प्रक्रियाएं, लंबे स्टार्टअप समय और अपेक्षाकृत उच्च मेमोरी उपयोग से पीड़ित होती हैं।


उदाहरण के लिए, यदि हम पिछले खंड से एप्लिकेशन चलाते हैं, तो इसे बहुत कम मात्रा में इनपुट डेटा खिलाया जाता है - 150 एमबी के बजाय लगभग 1Kb, तो ऐसा लगता है कि यह अनुचित रूप से लंबा समय लेगा और बहुत अधिक मेमोरी - लगभग 60 एमबी, इतनी छोटी फ़ाइल को संसाधित करने के लिए । हम निष्पादन समय के अलावा उपयोग की जाने वाली मेमोरी की मात्रा को प्रिंट करने के लिए -l विकल्प का उपयोग करते हैं।


 $ make small.txt $ /usr/bin/time -l java TopTen small.txt # -v on Linux instead of -l sed = 6 sit = 6 amet = 6 mauris = 3 volutpat = 3 vitae = 3 dolor = 3 libero = 3 tempor = 2 suscipit = 2 0.32 real 0.49 user 0.05 sys 59846656 maximum resident set size 

GraalVM हमें एक उपकरण देता है जो इस समस्या को हल करता है। हमने कहा कि ग्रेगल एक कंपाइलर लाइब्रेरी है और इसे कई अलग-अलग तरीकों से इस्तेमाल किया जा सकता है। उनमें से एक रन -टाइम में केवल-इन-टाइम को संकलित करने के बजाय, प्लेटफ़ॉर्म- भरोसेमंद निष्पादन योग्य छवि में समय के आगे संकलित कर रहा है। यह एक नियमित संकलक के समान है, जैसे कि gcc


 $ native-image --no-server TopTen classlist: 1,513.82 ms (cap): 2,333.95 ms setup: 3,584.09 ms (typeflow): 4,642.13 ms (objects): 3,073.58 ms (features): 156.34 ms analysis: 8,059.94 ms universe: 353.02 ms (parse): 1,277.02 ms (inline): 1,412.08 ms (compile): 10,337.76 ms compile: 13,776.23 ms image: 2,526.63 ms write: 1,525.03 ms [total]: 31,439.47 ms 

यह कमांड एक प्लेटफ़ॉर्म- topten बनाता है जिसे topten कहा जाता है। यह फ़ाइल JVM शुरू नहीं करती है, यह JVM से जुड़ी नहीं है, और इसमें JVM किसी भी तरह से शामिल नहीं है। native-image कमांड वास्तव में आपके जावा कोड और आपके द्वारा पूर्ण मशीन कोड में उपयोग किए जाने वाले जावा पुस्तकालयों को संकलित करता है। कचरा संग्राहक जैसे रनटाइम घटकों के लिए, हम अपने नए वीएम को SubstrateVM नाम से लॉन्च करते हैं, जो कि ग्रेगल की तरह जावा में भी लिखा गया है।


यदि आप उपयोग करने के लिए निर्भरता को देखते हैं, तो आप देखेंगे कि ये केवल मानक सिस्टम लाइब्रेरी हैं। हम केवल इस एक फाइल को एक ऐसी प्रणाली में स्थानांतरित कर सकते हैं जिसमें JVM कभी भी स्थापित नहीं हुआ है और इसे चलाने के लिए यह सत्यापित करें कि यह JVM या किसी अन्य फाइल का उपयोग नहीं करता है। Topten भी काफी छोटा है - निष्पादन योग्य कोड 6 एमबी से कम लेता है।


 $ otool -L topten # ldd topten on Linux topten: .../CoreFoundation.framework ... .../libz.1.dylib ... .../libSystem.B.dylib ... $ du -h topten 5.7M topten 

यदि हम इस निष्पादन योग्य को चलाते हैं, तो हम देखेंगे कि यह तीव्रता के एक क्रम के बारे में शुरू करता है और JVM के तहत चल रहे समान कार्यक्रम की तुलना में कम स्मृति परिमाण के एक आदेश का उपयोग करता है। लॉन्च इतना तेज़ है कि आपने यह नहीं देखा कि कितना समय लगा। यदि आप कमांड लाइन का उपयोग करते हैं, तो आपको जेवीएम के तहत एक छोटा, अल्पकालिक कार्यक्रम चलाने पर आमतौर पर मौजूद ठहराव महसूस नहीं होगा।


 $ /usr/bin/time -l ./topten small.txt sed = 6 sit = 6 amet = 6 mauris = 3 volutpat = 3 vitae = 3 dolor = 3 libero = 3 tempor = 2 suscipit = 2 0.02 real 0.00 user 0.00 sys 4702208 maximum resident set size 

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


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


3. जावास्क्रिप्ट, जावा, रूबी और आर का संयोजन


जावा के साथ, GraalVM में जावास्क्रिप्ट, रूबी, आर, और पायथन इंजन के नए कार्यान्वयन शामिल हैं। उन्हें ट्रूफ़ल नामक एक नए ढांचे का उपयोग करके लिखा गया है। यह ढांचा भाषा के दुभाषियों को बनाना संभव बनाता है जो सरल और उच्च-प्रदर्शन दोनों हैं। जब आप Truffle का उपयोग करते हुए एक भाषा दुभाषिया लिखते हैं, तो यह आपकी भाषा के लिए JIT संकलन प्रदान करने के लिए स्वतः ही Graal का उपयोग करेगा। इस प्रकार, ग्रेगल केवल जावा के लिए एक जेआईटी कंपाइलर और एओटी कंपाइलर नहीं है, यह जावास्क्रिप्ट, रूबी, आर और पायथन के लिए एक जेआईटी कंपाइलर भी हो सकता है।


GraalVM में तृतीय-पक्ष भाषाओं के लिए समर्थन का उद्देश्य विभिन्न भाषाओं के निष्पादन के लिए मौजूदा इंजनों के लिए एक पारदर्शी प्रतिस्थापन होना है। उदाहरण के लिए, हम Node.js के लिए "रंग" मॉड्यूल स्थापित कर सकते हैं:


 $ npm install --global color ... + color@3.0.0 added 6 packages in 14.156s 

फिर RGB मॉड्यूल को HSL में बदलने के लिए इस मॉड्यूल का उपयोग करके एक प्रोग्राम लिखें:


 var Color = require('color'); process.argv.slice(2).forEach(function (val) { print(Color(val).hsl().string()); }); 

और इसे सामान्य तरीके से चलाएं:


 $ node color.js '#42aaf4' hsl(204.89999999999998, 89%, 60.8%) 

GraalVM में विभिन्न भाषाओं के निष्पादन इंजन एक साथ काम करते हैं - एक एपीआई है जो आपको एक भाषा से दूसरी भाषा में लिखे गए प्रोग्राम में कोड चलाने की अनुमति देता है। और यह आपको बहुभाषी कार्यक्रम लिखने की अनुमति देता है - एक से अधिक प्रोग्रामिंग भाषा में लिखे गए प्रोग्राम।


यह आवश्यक हो सकता है यदि आप अपना अधिकांश कार्यक्रम एक भाषा में लिखते हैं, लेकिन किसी अन्य प्रोग्रामिंग भाषा में लिखी गई लाइब्रेरी का उपयोग करना चाहते हैं। उदाहरण के लिए, मान लें कि हमें Node.js में अपने सांख्यिक प्रतिनिधित्व के लिए CSS से एक रंग नाम बदलने के लिए एक आवेदन पत्र लिखने की आवश्यकता है, लेकिन हम स्वयं रूपांतरण लिखने के बजाय रूबी रंग पुस्तकालय का उपयोग करना चाहते हैं।


 var express = require('express'); var app = express(); color_rgb = Polyglot.eval('ruby', ` require 'color' Color::RGB `); app.get('/css/:name', function (req, res) { color = color_rgb.by_name(req.params.name).html() res.send('<h1 style="color: ' + color + '" >' + color + '</h1>'); }); app.listen(8080, function () { console.log('serving at http://localhost:8080') }); 

इस कोड में, हमने लिखा है कि हमें रूबी कोड को एक स्ट्रिंग के रूप में निष्पादित करने की आवश्यकता है, लेकिन ध्यान दें कि हमने यहां बहुत कुछ नहीं किया था - हमने केवल पुस्तकालयों को जोड़ा और फिर रूबी ऑब्जेक्ट को वापस कर दिया। रूबी में, हम इसे इस तरह उपयोग करेंगे: Color::RGB.by_name (name).html । यदि आप यह देखते हैं कि कैसे जावास्क्रिप्ट में बाद में color_rgb उपयोग किया जाता है, तो आप देखेंगे कि हम वास्तव में जावास्क्रिप्ट से समान विधियों को कॉल करते हैं, हालांकि ये रूबी ऑब्जेक्ट और विधियां हैं। और हम उन्हें जावास्क्रिप्ट स्ट्रिंग के रूप में पास करते हैं और परिणाम को जोड़ते हैं, जो एक जावास्क्रिप्ट स्ट्रिंग के साथ रूबी स्ट्रिंग है।


दोनों निर्भरताएं स्थापित करें - रूबी और जावास्क्रिप्ट।


 $ gem install color Fetching: color-1.8.gem (100%) Successfully installed color-1.8 1 gem installed $ npm install express + express@4.16.2 updated 1 package in 10.393s 

फिर आपको कुछ अतिरिक्त विकल्पों के साथ node शुरू करने की आवश्यकता है: --polyglot , यह कहने के लिए कि हमें अन्य भाषाओं और --jvm तक पहुंच की आवश्यकता है, क्योंकि डिफ़ॉल्ट रूप से निष्पादन योग्य node छवि में जावास्क्रिप्ट के अलावा कुछ भी शामिल नहीं है।


 $ node --polyglot --jvm color-server.js serving at http://localhost:8080 

और फिर अपने ब्राउज़र में हमेशा की तरह URL http: // localhost: 8080 / css / नारंगी (या कुछ अन्य रंग) पर जाएं।

आइए अधिक गंभीर उदाहरण बनाने की कोशिश करें, जो अधिक भाषाओं और मॉड्यूल का उपयोग करता है।


जावास्क्रिप्ट बहुत बड़े पूर्णांक का समर्थन नहीं करता है। मुझे कई मॉड्यूल मिले जैसे कि बड़े-पूर्णांक , लेकिन वे सभी अक्षम हैं क्योंकि किसी संख्या के घटकों को जावास्क्रिप्ट फ़्लोटिंग-पॉइंट संख्याओं के रूप में संग्रहीत करें। जावा में BigInteger वर्ग अधिक कुशल है, चलो इसका उपयोग बड़े पूर्णांकों के साथ कुछ अंकगणितीय संचालन करने के लिए करते हैं।


जावास्क्रिप्ट का रेखांकन रेखांकन के लिए कोई अंतर्निहित समर्थन नहीं है, जबकि R उत्कृष्ट रेखांकन खींचता है। आइए 3 डी अंतरिक्ष में त्रिकोणमितीय फ़ंक्शन के स्कैटर प्लॉट को खींचने के लिए R से svg मॉड्यूल का उपयोग करें।


दोनों ही मामलों में, हम API का उपयोग GraalVM से बहुभाषिकता का समर्थन करने के लिए करेंगे (इसके बाद पॉलीग्लॉट एपीआई के रूप में संदर्भित) और हम केवल जावास्क्रिप्ट में अन्य भाषाओं में कार्यक्रमों के निष्पादन के परिणामों को सम्मिलित कर सकते हैं।


 const express = require('express') const app = express() const BigInteger = Java.type('java.math.BigInteger') app.get('/', function (req, res) { var text = 'Hello World from Graal.js!<br> ' // Using Java standard library classes text += BigInteger.valueOf(10).pow(100) .add(BigInteger.valueOf(43)).toString() + '<br>' // Using R interoperability to create graphs text += Polyglot.eval('R', `svg(); require(lattice); x <- 1:100 y <- sin(x/10) z <- cos(x^1.3/(runif(1)*5+10)) print(cloud(x~y*z, main="cloud plot")) grDevices:::svg.off() `); res.send(text) }) app.listen(3000, function () { console.log('Example app listening on port 3000!') }) 

परिणाम देखने के लिए http: // localhost: 3000 / अपने ब्राउज़र में खोलें:

यह तीसरी चीज है जिसे हम ग्रेवालम के साथ कर सकते हैं - कई भाषाओं में लिखे गए प्रोग्राम चलाएं और इन भाषाओं के मॉड्यूल को एक प्रोग्राम में एक साथ उपयोग करें। हम इसे रनटाइम वातावरण और पुस्तकालयों को एकजुट करने के तरीके के रूप में प्रस्तुत करते हैं - आप उस प्रोग्रामिंग भाषा का उपयोग कर सकते हैं जो आपको लगता है कि वर्तमान कार्य को हल करने के लिए सबसे उपयुक्त है और आप जिस भी लाइब्रेरी में चाहते हैं, वह चाहे जिस भी भाषा में लिखी गई हो।


4. मंच-विशिष्ट भाषाओं में लिखे गए कार्यक्रमों का निष्पादन


एक और भाषा जो GraalVM का समर्थन करती है। C. GraalVM C कोड को उसी तरह निष्पादित कर सकती है जिस तरह से वह जावास्क्रिप्ट और रूबी में लिखे कार्यक्रमों को निष्पादित करती है।


GraalVM वास्तव में जो समर्थन करता है वह LLVM उपयोगिताओं के निष्पादन से उत्पन्न कोड का निष्पादन है, अर्थात। बिटकोड, सी के लिए प्रत्यक्ष समर्थन नहीं है। इसका मतलब है कि आप सी भाषा के लिए मौजूदा उपकरणों का उपयोग कर सकते हैं और अन्य जो एलएलवीएम का समर्थन करते हैं, जैसे कि सी ++, फोरट्रान और, संभवतः, भविष्य में अधिक भाषाएं। प्रदर्शन की सादगी के लिए, मैं गज़िप का एक विशेष संस्करण चलाता हूं, जिसे एक ही फाइल में इकट्ठा किया गया है ( स्टीफन मैककेमंट इस संस्करण का समर्थन करता है)। यह सरलता के लिए एक फ़ाइल में संयुक्त gzip स्रोत कोड और autoconf कॉन्फ़िगरेशन है। मुझे मैकओएस पर और क्लैंग के साथ काम करने के लिए कुछ चीजों को पैच करना था, लेकिन मैंने विशेष रूप से ग्रेवालम का समर्थन करने के लिए कुछ नहीं किया।


हम मानक clang (सी के लिए एलएलवीएम कंपाइलर) का उपयोग करके गज़िप को संकलित करते हैं और चाहते हैं कि यह हमें एलएलवीएम बिटकॉइन बनाए, न कि प्लेटफ़ॉर्म-विशिष्ट बिल्ड, क्योंकि ग्रेवालम इसे लॉन्च नहीं करेगा। मैं clang 4.0.1 का उपयोग कर रहा हूं।


 $ clang -c -emit-llvm gzip.c 

और फिर परिणाम को चलाएं, सीधे GraalVM से lli कमांड (LLVM बिटकोड इंटरप्रेटर) का उपयोग करते हुए। आइए मेरे gzip सिस्टम संग्रहकर्ता का उपयोग करके फ़ाइल को संपीड़ित करने का प्रयास करें, और फिर GraalVM के तहत चलने वाले gzip का उपयोग करके इसे अनज़िप करें।


 $ cat small.txt Lorem ipsum dolor sit amet... $ gzip small.txt $ lli gzip.bc -d small.txt.gz $ cat small.txt Lorem ipsum dolor sit amet... 

GraalVM में रूबी और पायथन कार्यान्वयन इन भाषाओं के लिए C में लिखे गए एक्सटेंशन को चलाने के लिए एक ही तकनीक का उपयोग करते हैं। इसका मतलब है कि आप वीएम के अंदर इन एक्सटेंशन को चला सकते हैं और इससे हम पुराने निष्पादन-विशिष्ट एक्सटेंशन इंटरफेस का उपयोग करने पर भी उच्च निष्पादन गति बनाए रख सकते हैं।


यह ग्रेवालम का उपयोग करने का चौथा तरीका है - प्लेटफ़ॉर्म-विशिष्ट भाषाओं में लिखे गए प्रोग्राम, जैसे कि C या C ++, साथ ही पायथन या रूबी जैसी भाषाओं के लिए एक्सटेंशन लॉन्च करना, जो कि JRuby जैसी इन भाषाओं के JVM कार्यान्वयन को बनाने में सक्षम नहीं हैं।


5. सभी प्रोग्रामिंग भाषाओं के लिए सामान्य उपकरण


यदि आप जावा में प्रोग्राम करते हैं, तो आप शायद आईडीई, डीबगर्स और प्रोफाइलर्स जैसे उच्च गुणवत्ता वाले टूल का उपयोग कर रहे हैं। सभी भाषाओं में यह टूलकिट नहीं है, लेकिन यदि आप उन भाषाओं का उपयोग कर सकते हैं जो GraalVM द्वारा समर्थित हैं।


GraalVM (फिलहाल जावा को छोड़कर) में सभी भाषाओं के लिए समर्थन एक सामान्य ढांचे - Truffle का उपयोग करके लागू किया गया है। यह हमें कार्यक्षमता बनाने की अनुमति देता है, उदाहरण के लिए, एक डिबगर, एक बार और सभी भाषाओं के लिए इसका उपयोग करें।


इसे आज़माने के लिए, हम सबसे सरल प्रोग्राम लिखेंगे - FizzBuzz , क्योंकि यह विज़ुअल है (यह स्क्रीन पर कुछ प्रिंट करता है) और इसकी स्पष्ट शाखाएँ हैं जो केवल कुछ पुनरावृत्तियों में उपयोग की जाती हैं। इस प्रकार, हमारे लिए ब्रेकप्वाइंट सेट करना आसान होगा। एक जावास्क्रिप्ट कार्यान्वयन के साथ शुरू करते हैं।


 function fizzbuzz(n) { if ((n % 3 == 0) && (n % 5 == 0)) { return 'FizzBuzz'; } else if (n % 3 == 0) { return 'Fizz'; } else if (n % 5 == 0) { return 'Buzz'; } else { return n; } } for (var n = 1; n <= 20; n++) { print(fizzbuzz(n)); } 

हम प्रोग्राम को हमेशा की तरह शुरू करते हैं, जेएसएल यूटिलिटी का उपयोग करके, ग्रेवालवीएम के तहत।


 $ js fizzbuzz.js 1 2 Fizz 4 Buzz Fizz 

हम प्रोग्राम को भी --inspect ध्वज के साथ चला सकते हैं। यह हमें एक लिंक देगा जिसे आप क्रोम में खोल सकते हैं और डिबगर में प्रोग्राम को रोक सकते हैं।


 $ js --inspect fizzbuzz.js Debugger listening on port 9229. To start debugging, open the following URL in Chrome: chrome-devtools://devtools/bundled/inspector.html?ws=127.0.0.1:9229/6c478d4e-1350b196b409 

आप FizzBuzz कोड में एक ब्रेकपॉइंट सेट कर सकते हैं और फिर निष्पादन जारी रख सकते हैं। जब प्रोग्राम निष्पादन को बाधित करता है, तो हम डीबगर में वेरिएबल n का मान देखेंगे और हम प्रोग्राम के निष्पादन को जारी रख सकते हैं या डीबगर इंटरफ़ेस का अध्ययन कर सकते हैं।

Chrome में डीबगर आमतौर पर जावास्क्रिप्ट के लिए उपयोग किया जाता है, लेकिन जावास्क्रिप्ट में GraalVM के लिए अन्य भाषाओं से अलग कुछ भी नहीं है। --inspect ध्वज भी उपलब्ध है और पायथन, रूबी और आर कार्यान्वयन में काम करता है। मैंने आपको प्रत्येक कार्यक्रम का स्रोत नहीं दिखाया है, लेकिन वे उसी तरह से चलते हैं और आप उनमें से प्रत्येक के लिए Chrome में समान डीबगर प्राप्त करते हैं।


 $ graalpython --jvm --inspect fizzbuzz.py 


 $ ruby --inspect fizzbuzz.rb 


 $ Rscript --inspect fizzbuzz.r 


एक अन्य उपकरण जिसे आप जावा से परिचित कर सकते हैं, वह है विजुअलवीएम। यह एक उपयोगकर्ता इंटरफ़ेस प्रदान करता है जिसके माध्यम से आप अपने स्थानीय मशीन पर या नेटवर्क निष्पादन के माध्यम से प्रोग्राम निष्पादन के विभिन्न पहलुओं, जैसे स्मृति उपयोग या थ्रेड निष्पादन का निरीक्षण करने के लिए एक रनिंग जेवीएम से जुड़ सकते हैं।


GraalVM में VisualVM एक मानक jvisualvm उपयोगिता के रूप में शामिल है।


 $ jvisualvm &> /dev/null & 

यदि हम TopTen Java प्रोग्राम TopTen , तो हम VisualVM चलाते हैं, तो हम मेमोरी उपयोग का निरीक्षण कर सकते हैं या, उदाहरण के लिए, मेमोरी सामग्री का एक स्नैपशॉट लें और देखें कि हम किस प्रकार की ऑब्जेक्ट्स का उपयोग कर रहे हैं।


 $ java TopTen large.txt 


मैंने रूबी में इस कार्यक्रम को रनटाइम में स्मृति में कुछ कचरा उत्पन्न करने के लिए लिखा था।


 require 'erb' x = 42 template = ERB.new <<-EOF The value of x is: <%= x %> EOF loop do puts template.result(binding) end 

यदि आप JVM - JRuby पर मानक रूबी कार्यान्वयन चलाते हैं, तो आपको VisualVM से निराशा होगी क्योंकि आप अपनी भाषा में वस्तुओं के बजाय केवल आंतरिक जावा ऑब्जेक्ट देखेंगे।


यदि आप GraalVM के लिए रूबी के संस्करण का उपयोग करते हैं, तो VisualVM रूबी वस्तुओं को पहचानता है। हमें VisualVM का उपयोग करने के लिए --jvm विकल्प का उपयोग करने की आवश्यकता है यह रूबी के मूल संस्करणों का समर्थन नहीं करता है।


 $ ruby --jvm render.rb 

, , Java , , , Summary, Ruby Heap Ruby .

Truffle — - Nexus . Truffle , , API Truffle' , , Truffle, .


, GraalVM — , . Truffle GraalVM , VisualVM.


6. JVM


, , , Java . API org.graalvm.polyglot , .


 import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; public class ExtendJava { public static void main(String[] args) { String language = "js"; try (Context context = Context.newBuilder().allowNativeAccess(true).build()) { for (String arg: args) { if (arg.startsWith("-")) { language = arg.substring(1); } else { Value v = context.eval(language, arg); System.out.println(v); } } } } } 

javac java GraalVM, org.graalvm.* classpath , .. .


 $ javac ExtendJava.java $ java ExtendJava '14 + 2' 16 $ java ExtendJava -js 'Math.sqrt(14)' 3.7416573867739413 $ java ExtendJava -python '[2**n for n in range(0, 8)]' [1, 2, 4, 8, 16, 32, 64, 128] $ java ExtendJava -ruby '[4, 2, 3].sort' [2, 3, 4] 

, — , node ruby , GraalVM.


GraalVM — Java . Polyglot API “” Java , .


7. -


GraalVM , , — , , GraalVM, - . , JavaScript , V8, Python — CPython , .. . GraalVM — Polyglot .


GraalVM, , JavaScript. Polyglot , , :


 $ graalvm-1.0.0-rc1/Contents/Home/jre/lib/svm/bin/rebuild-images libpolyglot 

C, , , GraalVM, . ExtendJava , , .


 #include <stdlib.h> #include <stdio.h> #include <polyglot_api.h> int main(int argc, char **argv) { graal_isolate_t *isolate = NULL; graal_isolatethread_t *thread = NULL; if (graal_create_isolate(NULL, &isolate) != 0 || (thread = graal_current_thread(isolate)) == NULL) { fprintf(stderr, "initialization error\n"); return 1; } poly_context context = NULL; if (poly_create_context(thread, NULL, 0, &context) != poly_ok) { fprintf(stderr, "initialization error\n"); return 1; } char* language = "js"; for (int n = 1; n < argc; n++) { if (argv[n][0] == '-') { language = &argv[n][1]; } else { poly_value result = NULL; if (poly_context_eval(thread, context, language, "unicalc", argv[n], &result) != poly_ok) { fprintf(stderr, "eval error\n"); return 1; } char buffer[1024]; size_t length; if (poly_value_to_string_utf8(thread, result, buffer, sizeof(buffer), &length) != poly_ok) { fprintf(stderr, "to string error\n"); return 1; } buffer[length] = '\0'; printf("%s\n", buffer); poly_destroy_handle(thread, result); } } return 0; } 

, polyglot GraalVM. , , JVM.


 $ clang -Igraalvm-1.0.0-rc1/Contents/Home/jre/lib/polyglot / -rpath graalvm-1.0.0-rc1/Contents/Home / -Lgraalvm-1.0.0-rc1/Contents/Home/jre/lib/polyglot / -lpolyglot extendc.c -o extendc $ otool -L extendc extendc: .../libpolyglot.dylib ... .../libSystem.B.dylib ... 

 $ ./extendc '14 + 2' 16 $ ./extendc -js 'Math.sqrt(14)' 3.7416573867739413 $ ./extendc -python '[2**n for n in range(0, 8)]' [1, 2, 4, 8, 16, 32, 64, 128] 

, GraalVM — - , , GraalVM.


8. Java -


Java , , , , - , . Java - , JVM , .


GraalVM Java , , - , . , , Java JVM.


, Apache SIS , ( ) . SIS 0.8, http://sis.apache.org/ jar.


 import org.apache.sis.distance.DistanceUtils; public class Distance { public static void main(String[] args) { final double aLat = Double.parseDouble(args[0]); final double aLong = Double.parseDouble(args[1]); final double bLat = Double.parseDouble(args[2]); final double bLong = Double.parseDouble(args[3]); System.out.printf("%.2f km%n", DistanceUtils.getHaversineDistance(aLat, aLong, bLat, bLong)); } public static double distance(IsolateThread thread, double aLat, double aLong, double bLat, double bLong) { return DistanceUtils.getHaversineDistance(aLat, aLong, bLat, bLong); } } 

, -


 $ javac -cp sis.jar -parameters Distance.java $ java -cp sis.jar:. Distance 51.507222 -0.1275 40.7127 -74.0059 5570.25 km 

, topten .


 $ native-image --no-server -cp sis.jar:. Distance ... $ ./distance 51.507222 -0.1275 40.7127 -74.0059 5570.25 km 

, . , @CEntryPoint


 ... import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.c.function.CEntryPoint; public class Distance { ... @CEntryPoint(name = "distance") public static double distance(IsolateThread thread, double a_lat, double a_long, double b_lat, double b_long) { return DistanceUtils.getHaversineDistance(a_lat, a_long, b_lat, b_long); } ... } 

javac , GraalVM API classpath . C .


 $ native-image --no-server -cp sis.jar:. -H:Kind=SHARED_LIBRARY \ -H:Name=libdistance $ otool -L libdistance.dylib # .so on Linux libdistance.dylib: .../libdistance.dylib ... .../CoreFoundation.framework ... .../libz.1.dylib ... .../libSystem.B.dylib ... $ du -h libdistance.dylib 4.8M libdistance.dylib 

, . , : VM , , .


 #include <stdlib.h> #include <stdio.h> #include <libdistance.h> int main(int argc, char **argv) { graal_isolate_t *isolate = NULL; graal_isolatethread_t *thread = NULL; if (graal_create_isolate(NULL, &isolate) != 0 || (thread = graal_current_thread(isolate)) == NULL) { fprintf(stderr, "initialization error\n"); return 1; } double a_lat = strtod(argv[1], NULL); double a_long = strtod(argv[2], NULL); double b_lat = strtod(argv[3], NULL); double b_long = strtod(argv[4], NULL); printf("%.2f km\n", distance(thread, a_lat, a_long, b_lat, b_long)); return 0; } 

, ( LD_LIBRARY_PARTH=. Linux)


 $ clang -I. -L. -ldistance distance.c -o distance $ otool -L distance distance: .../libdistance.dylib ... .../libSystem.B.dylib ... $ ./distance 51.507222 -0.1275 40.7127 -74.0059 5570.25 km 

GraalVM — java - , JVM


9.


Polyglot — Oracle. Oracle Database Multilingual Engine (MLE), GraalVM SQL.


, front-end, JavaScript email , JavaScript validator . - , SQL PL/SQL. , .


MLE Docker :


https://oracle.imtqy.com/oracle-db-mle/releases/0.2.7/docker/


Docker Daemon.


 $ docker load --input mle-docker-0.2.7.tar.gz 

, Docker, , ( ), Bash .


 $ docker run mle-docker-0.2.7 $ docker ps $ docker exec -ti <container_id> bash -li 

sqlplus ( SQL ), Bash, , , .


 $ sqlplus scott/tiger@localhost:1521/ORCLCDB 

, sqlplus . , Bash Docker, dbjs , . sqlplus .


 $ npm install validator $ npm install @types/validator $ dbjs deploy -u scott -p tiger -c localhost:1521/ORCLCDB validator $ sqlplus scott/tiger@localhost:1521/ORCLCDB 

validator SQL .


 SQL> select validator.isEmail('hello.world@oracle.com') from dual; VALIDATOR.ISEMAIL('HELLO.WORLD@ORACLE.COM') ------------------------------------------- 1 SQL> select validator.isEmail('hello.world') from dual; VALIDATOR.ISEMAIL('HELLO.WORLD') -------------------------------- 0 

, GraalVM — , GraalVM, Oracle. , front-end back-end, , , .


10. GraalVM


Oracle Labs JavaScript, R, Ruby, Python C , Truffle, GraalVM.


Truffle — java , (AST). AST — , , , , , . , , Truffle Graal JIT , AST .


Truffle, GraalVM , , DSL. Truffle Graal , , Truffle — GraalVM. , , , , . , , . Oracle labs Ruby , , .


, , , SimpleLanguage — Truffle, JavaScript. , , , , , if .


, Truffle Oracle Labs, SmallTalk , Newspeak Lisp . Lisp , .


निष्कर्ष


GraalVM — , , . , , , , .


GraalVM, http://www.graalvm.org/ . , , .


, , . , GraalVM @ChrisGSeaton @shelajev .


: Oleg Šelajev , Olya Gupalo Doug Simon

Source: https://habr.com/ru/post/hi433432/


All Articles