Первоначально опубликовано в Deepu.ech Отказ
Вы слышали о Граалвм ? Если вы еще не должны проверить это. Это захватывающая технология, вы знаете, что получает разработчик Polyglot Point 😉
С сайта:
Graalvm – это универсальная виртуальная машина для беговых приложений, написанных в JavaScript, Python, Ruby, R, r, JVM-языкам, такими как Java, Scala, Groovy, Kotlin, Clojure и LLVM, такие языки, как C и C ++.
Граалвм – один из своего рода. Это полиглот VM, разработанный в Oracle и отдельно от своих возможностей многоглот, он также был доказан, что является довольно исполнительным и имеет меньшую площадь памяти. Он имеет поддержку для строительства нативных изображений и некоторых современных структур Java Microvize, таких как Микронаут и Quarkus Поддержка Graalvm, поскольку он обеспечивает более быстрый запуск и меньший след, который идеально подходит для архитектур микровиссов.
Так каковы возможности Граальвма? Давайте посмотрим
Hraalvm Особенности
- Снижение замены JDK – Некоторые тесты показывают Graalvm, чтобы быть быстрее и меньше памяти, голодными, чем другие поставщики JDK, я лично не запускал никаких ориентиров
- Падение замены Nodejs – использует Graalvm вместо V8, как двигатель для Nodejs
- Быстрое время выполнения для Ruby и R чем реализации по умолчанию
- Передние (AOT) скомпилированные родные изображения
- Полиглот возможностей – Java (любой язык JVM), JavaScript, Ruby, Python, R, C/C ++/RUST (LLVM) вместе с языковой совместимостью
- Рамки реализации трюфельных языков реализовать сторонняя языковая поддержка
Установите Graalvm.
Прежде чем мы начнем, позвольте нам настроить Graalvm. Я использовал SDKMAN, вы также можете следовать Это Если вы хотите установить его вручную.
- Первый Установить SDKMAN Если у вас нет этого уже
sdk list java # you can use a newer version if available sdk install java 19.3.1.r11-grl sdk use java 19.3.1.r11-grl # Check everything java -version node -v lli --version
Вышепередается установится Graalvm и настроить его как Java
, Узел
и Лли
контекст. Пожалуйста, обратите внимание на : Если вы начнете новую сеанс терминала, вам придется запустить SDK Используйте Java 19.3.1.R11-GRL
опять таки.
- Установите MLVM Toolchain, Python и Ruby служба поддержки
gu install llvm-toolchain export LLVM_TOOLCHAIN=\$(lli --print-toolchain-path) gu install python gu install ruby
- Установите ржавчину
curl https://sh.rustup.rs -sSf | sh
Вот и мы готовы катиться!
Как разработчик полиглота, Graalvm довольно интересен для меня, так как я могу использовать многие языки, которые я люблю вместе, используя лучшие части от каждого. Давайте рассмотрим возможности полиглот, предлагаемые Graalvm, обратите внимание, что поддержка Python, Ruby, R и ржавчины все еще находятся на экспериментальной стадии, и, следовательно, ваш пробег может варьироваться. Мы построим программу сегодня, используя Java, JavaScript, Ruby, Rust, Python и C ++.
Я хотел использовать ржаветь и идти так хорошо. Пока ржавчину в основном работает через Graalvm Лли
Командная строка, она имеет много ограничений при встроенном режиме Polyglot. После многих возобновляемых мне удалось работать. Для Голанга это может быть возможно с Это Go Llvm Compiler, как показано на рисунке здесь Но он имеет свой собственный набор вопросов, когда я пытался. Так что я уже отказался от Голанга. Дайте мне знать, если кто-нибудь из вас получил работу.
У нас будет простое (глупуе 😉) приложение, написанное в Java, который составляет методы с разных языков для каждого шага из Java
- Python : Фильтрует число фибоначчи из данного входного массива
- JavaScript : Найдите кубик каждого номера в выходе на массиве с предыдущего шага
- C++ : Получите сумму чисел в выходной массиве с предыдущего шага
- Ржавчина : Найдите кубик-корень числа с предыдущего шага
- Ruby : Найти факториал числа с предыдущего шага
- Java : Наконец-то распечатайте результат (это также программа обертки)
Если вы предпочитаете более сложный пример, проверьте Это вне.
Шаг 1: Джава
Начнем с нашей программы Java Wrapper Polyglot.java.
import java.io.*; import org.graalvm.polyglot.*; class Polyglot { // We create a polyglot context to evaluate source files static Context polyglotCtx = Context.newBuilder().allowAllAccess(true).build(); // Utility method to load and evaluate a source file static Value loadSource(String language, String fileName) throws IOException { File file = new File(fileName); Source source = Source.newBuilder(language, file).build(); return polyglotCtx.eval(source); } // Utility method to convert arrays between languages static int[] getIntArrayFromValue(Value val) { int[] out = new int[(int) val.getArraySize()]; if (val.hasArrayElements()) { for (int i = 0; i < val.getArraySize(); i++) { out[i] = val.getArrayElement(i).asInt(); } } return out; } public static void main(String[] args) throws IOException { int[] input = new int[] { 4, 2, 8, 5, 20, 1, 40, 13, 23 }; /* PYTHON: Get the Fibonacci numbers from the array */ loadSource("python", "pythonpart.py"); Value getFibonacciNumbersFn = polyglotCtx.getBindings("python").getMember("getFibonacciNumbers"); int[] fibNumbers = getIntArrayFromValue(getFibonacciNumbersFn.execute(input)); /* JAVASCRIPT: Find cube of numbers in the output array */ loadSource("js", "jspart.js"); Value findCubeOfNumbersFn = polyglotCtx.getBindings("js").getMember("findCubeOfNumbers"); int[] sqrNumbers = getIntArrayFromValue(findCubeOfNumbersFn.execute(fibNumbers)); /* C++: Get the sum of the numbers in the output array */ loadSource("llvm", "cpppart"); Value getSumOfArrayFn = polyglotCtx.getBindings("llvm").getMember("getSumOfArray"); int sum = getSumOfArrayFn.execute(sqrNumbers, sqrNumbers.length).asInt(); /* Rust: Find the cube root of sum */ Value cubeRootFn = loadSource("llvm", "rustpart.bc").getMember("cube_root"); // println! macro does not work from Rust when embedded, some issue with mangling System.out.println("Rust => Find cube root of the number"); Double cubeRoot = cubeRootFn.execute(sum).asDouble(); /* RUBY: Find factorial of the number */ Value factorialFn = loadSource("ruby", "rubypart.rb"); long out = factorialFn.execute(cubeRoot).asLong(); System.out.println("Sum: " + sum); System.out.println("Cube Root: " + cubeRoot); System.out.println("Factorial: " + out); } }
Утиливые функции должны упростить код, теперь давайте посмотрим на каждый шаг, где он составляет функции.
Шаг 2: Python
Мы выполняем getfibonaccinumbers
Функция, расположенная в файле pythonpart.py
и прохождение нашего входного массива.
/* PYTHON: Get the Fibonacci numbers from the array */ loadSource("python", "pythonpart.py"); Value getFibonacciNumbersFn = polyglotCtx.getBindings("python").getMember("getFibonacciNumbers"); int[] fibNumbers = getIntArrayFromValue(getFibonacciNumbersFn.execute(input));
Давайте посмотрим на pythonpart.py
, это стандартная программа Python, которая принимает массив и фильтрует номера фибоначчи из него и возвращает результирующий массив.
import math def isPerfectSquare(num): n = int(math.sqrt(num)) return (n * n == num) # Function to check if the number is in Fibonacci or not def getFibonacciNumbers(array): print("Python => Filtering Fibonacci number from the array"); out = [] n = len(array) count = 0 for i in range(n): if (isPerfectSquare(5 * array[i] * array[i] + 4) or isPerfectSquare(5 * array[i] * array[i] - 4)): out.append(array[i]); count = count + 1 if (count == 0): print("None present"); return out
Шаг 3: JavaScript
Мы выполняем FindCubeofnumbers
Функция, расположенная в файле jspart.js
и прохождение результата из функции Python.
/* JAVASCRIPT: Find cube of numbers in the output array */ loadSource("js", "jspart.js"); Value findCubeOfNumbersFn = polyglotCtx.getBindings("js").getMember("findCubeOfNumbers"); int[] sqrNumbers = getIntArrayFromValue(findCubeOfNumbersFn.execute(fibNumbers));
Давайте посмотрим на jspart.js
, это стандартная функция JavaScript, которая принимает массив и отображает элементы и возвращает массив. Но нам пришлось позвонить Array.prototype.map.call
вместо просто array.map
Поскольку массив, пройденный Java, не является стандартным массивом JS.
function findCubeOfNumbers(array) { console.log("JS => Getting cube of numbers in the array"); return Array.prototype.map.call(array, (it) => Math.pow(it, 3)); }
Шаг 4: C ++
Мы выполняем gentumofarray
Функция, расположенная в CPPPART
бинарный файл. Мы проходим результат от функции JS и длину массива здесь. Мы должны использовать скомпилированный бинарный здесь, в отличие от Python, Ruby и JavaScript, которые интерпретируются языками.
/* C++: Get the sum of the numbers in the output array */ loadSource("llvm", "cpppart"); Value getSumOfArrayFn = polyglotCtx.getBindings("llvm").getMember("getSumOfArray"); int sum = getSumOfArrayFn.execute(sqrNumbers, sqrNumbers.length).asInt();
Источник двоичного в CPPPART.CPP
файл. Который скомпилирован с помощью ниже
export LLVM_TOOLCHAIN=$(lli --print-toolchain-path) $LLVM_TOOLCHAIN/clang++ -shared cpppart.cpp -lpolyglot-mock -o cpppart
Давайте посмотрим на CPPPART.CPP
Это стандартная программа C ++, которая экспортирует функцию. Это принимает массив и его длина как аргументы и возвращает номер
#includeusing namespace std; // Function to find the sum of integer array // extern "C" is required to suppress mangling extern "C" int getSumOfArray(int array[], int size) { printf("C++ => Find sum of numbers in an array\n"); int i, sum = 0; for(i = 0; i < size; i++) { sum += array[i]; } return sum; }
Шаг 5: ржавчина
Мы выполняем Cube_root
Функция, расположенная в файле Rustpart.bc
, скомпилирован от rustpart.rs.
. Мы проходим результат от функции C ++ здесь.
/* Rust: Find the cube root of sum */ Value cubeRootFn = loadSource("llvm", "rustpart.bc").getMember("cube_root"); // println! macro does not work from Rust when embedded, some issue with mangling System.out.println("Rust => Find cube root of the number"); Double cubeRoot = cubeRootFn.execute(sum).asDouble();
Давайте посмотрим на Rustpart.rs
, это стандартная функция ржавчины, которая принимает номер, находит свой кубик и возвращает его. Но нам нужно указать # [no_mangle]
Аннотация и мы не можем использовать какие-либо ящики, а также видимо. Смерты функции с примитивными ARGS/выходом, кажется, работают, но более сложные функции не работают при встроенном.
#[no_mangle] fn cube_root(arg: f64) -> f64 { arg.cbrt() } fn main(){}
Мы компилируем источник ржавчины в двоичный код, используя Rustc
Компилятор с --emit = llvm-bc
флаг
rustc --emit=llvm-bc rustpart.rs
Шаг 6: Ruby
Мы выполняем факториал
Функция, расположенная в файле RUBYPART.RB
Отказ Мы передаем результат от функции ржавчины здесь.
/* RUBY: Find factorial of the number */ Value factorialFn = loadSource("ruby", "rubypart.rb"); long out = factorialFn.execute(cubeRoot).asLong();
Давайте посмотрим на RUBYPART.RB
Это стандартная функция Ruby Lambda, которая принимает номер и возвращает его факториал.
factorial = -> (num) { puts "Ruby => Find factorial of the number" (1..num).inject {|product, num| product * num } }
И, наконец, мы распечатаем выходы с Java.
Запустите программу
Чтобы запустить эту программу, нам нужно сначала компилировать файлы C ++, Rust и Java, а затем запустить его с помощью JVM, предоставляемой GRALVM. Ниже приведены шаги, вы можете сохранить это как Run.sh
и выполнить это.
export LLVM_TOOLCHAIN=$(lli --print-toolchain-path) $LLVM_TOOLCHAIN/clang++ -shared cpppart.cpp -lpolyglot-mock -o cpppart || exit rustc --emit=llvm-bc rustpart.rs || exit javac Polyglot.java && java Polyglot
Это даст выход ниже:
Разве это не было так весело? Так что такая способность полиглота полезна? Хорошо, что зависит, возможности полиглот Граалвм все еще не готовы к производству Но он все еще полезен, поскольку он открывает дверь для совместимости на реальную языку, представьте, что это может использовать библиотеку с любого языка из вашей программы, это уже возможно для многих библиотек C, Ruby, R, JS и Java с Graalvm, а как Поддержка становится лучше, мы сможем освободиться от ограниченности одного языка. Граалвм, кажется, гораздо быстрее для языков, таких как Ruby, чем стандартный Croby или JRuby, например, и это многообещается, поскольку это будет означать, что вам не придется беспокоиться о накладных расходах при включении нескольких языков в вашей программе.
Граалвм – одна из самых революционных технологий, которые я встречал в последнее время И я надеюсь, что языковая поддержка полиглота становится готовой к производству, вскоре в сочетании с собственными возможностями изображения Это будет очень мощная платформа для по-настоящему полиглот-приложения.
Если вам нравится эта статья, пожалуйста, оставьте вроде или комментарий.
Вы можете следовать за мной на Twitter и LinkedIn Отказ
Обложка изображений кредита: на основе официальных логотипов соответствующих проектов.
Оригинал: “https://dev.to/deepu105/polyglot-inception-with-graalvm-why-because-it-s-fun-aa”