क्या पायथन को मशीन कोड में संकलित करना संभव है?


128

मशीन कोड में अजगर (संभवतः एक मध्यवर्ती सी प्रतिनिधित्व के माध्यम से) को संकलित करना कितना संभव होगा?

संभवत: इसे पायथन रनटाइम लाइब्रेरी से लिंक करने की आवश्यकता होगी, और पायथन मानक पुस्तकालय के कुछ हिस्से जो स्वयं पायथन थे उन्हें संकलित (और लिंक किए गए) भी करने की आवश्यकता होगी।

इसके अलावा, यदि आप भावों का गतिशील मूल्यांकन करना चाहते हैं, तो आपको पायथन इंटरप्रेटर को बंडल करना होगा, लेकिन शायद पायथन का एक सबसेट जो इसे अभी भी उपयोगी नहीं होने देगा।

क्या यह कोई गति और / या स्मृति उपयोग लाभ प्रदान करेगा? संभवतः पायथन दुभाषिया के स्टार्टअप समय को समाप्त कर दिया जाएगा (हालांकि साझा पुस्तकालयों को अभी भी स्टार्टअप पर लोड करने की आवश्यकता होगी)।


2
Btw, आपका प्रश्न IMHO स्पष्ट होगा यदि आपने ऑब्जेक्ट कोड के बजाय "मशीन कोड" के लिए कहा है।
टॉर्स्टन मारेक

जवाबों:


31

ShedSkin Python-to-C ++ कंपाइलर आज़माएं , लेकिन यह एकदम सही है। इसके अलावा Psyco - Python JIT है अगर केवल स्पीडअप की जरूरत है। लेकिन IMHO यह प्रयास के लायक नहीं है। कोड के स्पीड-क्रिटिकल भागों के लिए सबसे अच्छा समाधान यह होगा कि उन्हें C / C ++ एक्सटेंशन के रूप में लिखा जाए।


5
FYI करें, ShedSkin ने Windows समर्थन को गिरा दिया।
सोरिन

2
@ सोरीन: ठीक है, आज यह विंडोज़ का समर्थन करता है ... code.google.com/p/shedskin/downloads/…

2
सबसे अच्छा समाधान, स्पीडवाइज़ , अभी भी PyPy हो सकता है ।
Cs टिम्मरमैन

shedskin के बारे में दो साल में इस पर कोई काम नहीं हुआ है। :(
पर्किन्स

53

जैसा कि @Greg Hewgill कहती है, अच्छे कारण हैं कि यह हमेशा संभव नहीं है। हालांकि, कुछ प्रकार के कोड (जैसे बहुत एल्गोरिदम कोड) को "वास्तविक" मशीन कोड में बदल दिया जा सकता है।

कई विकल्प हैं:

  • Psyco का उपयोग करें , जो मशीन कोड को गतिशील रूप से उत्सर्जित करता है। आपको ध्यान से चुनना चाहिए कि किन विधियों / कार्यों को परिवर्तित करना है, हालांकि।
  • उपयोग Cython है, जो एक Python- है की तरह भाषा है कि एक अजगर सी विस्तार में संकलित किया गया है
  • PyPy का उपयोग करें , जिसमें RPython का एक अनुवादक है ( Python का एक सीमित उपसमूह जो Python की कुछ सबसे "गतिशील" विशेषताओं का समर्थन नहीं करता है) C या LLVM के लिए।
    • PyPy अभी भी अत्यधिक प्रयोगात्मक है
    • सभी एक्सटेंशन मौजूद नहीं होंगे

उसके बाद, आप एक बाइनरी में सब कुछ डालने के लिए मौजूदा पैकेज (फ्रीज, Py2exe, PyInstaller) का उपयोग कर सकते हैं।

सभी में: आपके प्रश्न का कोई सामान्य उत्तर नहीं है। यदि आपके पास पायथन कोड है जो प्रदर्शन-महत्वपूर्ण है, तो जितना संभव हो उतना अंतर्निहित कार्यक्षमता का उपयोग करने का प्रयास करें (या "मैं अपना पायथन कोड कैसे तेज करूं" प्रश्न पूछें)। यदि वह मदद नहीं करता है, तो कोड को पहचानने का प्रयास करें और इसे C (या साइथॉन) में पोर्ट करें और एक्सटेंशन का उपयोग करें।


3
Pypy Psyco का उत्तराधिकारी है
bcattle

19

py2c ( https://github.com/pradyun/Py2C ) python कोड को c / c ++ में बदल सकता है I मैं py2c का अकेला डेवलपर हूं।


यह एक उपयोगी उपकरण की तरह दिखता है। क्या अब भी इसे बनाए रखा जा रहा है?
एंडरसन ग्रीन

@AndersonGreen यह एक प्रारंभिक विकास चरण में है जब पिछली बार मैं इस पर काम कर रहा था (शायद अब इसी तरह)। मैंने प्रोजेक्ट छोड़ दिया है क्योंकि I̶'̶m̶ ̶b̶u̶s̶y l मैं आलसी हूं। यदि आपने "महत्वपूर्ण" टेक्स्ट नहीं देखा है, तो यह अब GitHub में चला गया है।
रामचंद्र आप्टे

लिंक अनवांटेड-इंस्टॉलर को इंगित करता है , जो एक अलग प्रोजेक्ट प्रतीत होता है। क्या GyHub पर अभी भी py2c उपलब्ध है?
एंडरसन ग्रीन

@AndersonGreen वाह कि इतने लंबे समय तक किसी का ध्यान नहीं गया था! यहाँ तुम जाओ।
रामचंद्र आपटे

पर लिंक code.google.com/p/py2c अभी भी, unvanquished-संस्थापक की ओर इशारा करता है, तो यह अब अपडेट करने की आवश्यकता।
एंडरसन ग्रीन

15

PyPy पायथन में पायथन को फिर से लागू करने के लिए एक परियोजना है, मूल कोड के कार्यान्वयन के रूप में कार्यान्वयन रणनीतियों (जेवीएम के साथ एक वीएम होने के नाते जेवीएम, आदि का उपयोग करके)। उनके संकलित सी संस्करण औसत रूप से सीपीथॉन की तुलना में धीमी गति से चलते हैं लेकिन कुछ कार्यक्रमों के लिए बहुत तेज हैं।

Shedskin एक प्रायोगिक पायथन-टू-सी ++ कंपाइलर है।

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


3
साइथॉन पाइरेक्स का अधिक व्यापक रूप से उपयोग किया जाने वाला, अधिक सक्रिय रूप से विकसित अनुकूल कांटा है।
माइक ग्राहम

"पायथन की अच्छी, उच्च-स्तरीय, आसानी से उपयोग की जाने वाली दुनिया और सी की गन्दा, निम्न-स्तरीय दुनिया" - मजेदार मैं बस सोच रहा था कि कैसे सी और कोडांतरक "अच्छा" और सरल है, और पायथन में रहता है " गन्दा "," उच्च-स्तरीय "दुनिया
उलट अभियंता

14

Nuitka C ++ कंपाइलर के लिए एक पायथन है जो लिबायथॉन के खिलाफ लिंक करता है। यह एक अपेक्षाकृत नई परियोजना प्रतीत होती है। लेखक ने पाइस्टोन बेंचमार्क पर सीपीथॉन पर गति में सुधार का दावा किया है ।


10

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

Py2.exe जैसी उपयोगिताओं हैं जो एक पायथन प्रोग्राम और रनटाइम को एक एकल निष्पादन योग्य (जहां तक ​​संभव हो) में बंडल करेगी।


1
क्या होगा यदि मेरा लक्ष्य यह सुनिश्चित करना है कि कोड संकलित करता है, क्योंकि सांख्यिकीय रूप से संकलित भाषाएं हैं (कम से कम मेरी राय में) रन समय पर उड़ाने की संभावना कम है? क्या यह निर्धारित करना संभव है कि कुछ foo.xअभिव्यक्ति काम fooनहीं करेगी क्योंकि xउस समय नहीं होगा जब इसे बुलाया जाता है। क्या पायथन के लिए कोई स्थिर कोड चेकर हैं? पायथन को एक .नेट असेंबली में संकलित किया जा सकता है ...
हामिश ग्रुबीजन

10

Pyrex Python भाषा का एक उपसमूह है जो C से संकलित होता है, उस लड़के द्वारा किया जाता है जो पहले Pyon के लिए सूची निर्मित समझ रखता है। यह मुख्य रूप से रैपर के निर्माण के लिए विकसित किया गया था, लेकिन इसका उपयोग अधिक सामान्य संदर्भ में किया जा सकता है। साइथन पाइरेक्स का एक अधिक सक्रिय रूप से बनाए रखा कांटा है।


2
साइथॉन पाइरेक्स का अधिक-व्यापक रूप से उपयोग किया जाने वाला, अधिक सक्रिय रूप से विकसित अनुकूल कांटा है।
माइक ग्राहम

5

कुछ अतिरिक्त संदर्भ:


3

Jython में JVM bytecode को संकलित करने वाला एक कंपाइलर है। बाइटकोड पूरी तरह से गतिशील है, जैसे कि पायथन भाषा ही! बहुत ही शांत। (हाँ, जैसा कि ग्रेग हेवगिल के जवाब में कहा गया है, बायटेकोड जाइथन रनटाइम का उपयोग करता है, और इसलिए जाइथन जार फ़ाइल को आपके ऐप के साथ वितरित किया जाना चाहिए।)


2

Psyco एक तरह का जस्ट-इन-टाइम (JIT) कंपाइलर है: पायथन के लिए डायनामिक कंपाइलर, कोड को 2-100 गुना तेजी से चलाता है, लेकिन इसके लिए ज्यादा मेमोरी की जरूरत होती है।

संक्षेप में: यह आपके मौजूदा पायथन सॉफ़्टवेयर को बहुत तेज़ी से चलाता है, आपके स्रोत में कोई बदलाव नहीं करता है लेकिन यह सी कोड संकलक के समान ऑब्जेक्ट कोड को संकलित नहीं करता है।


2

जवाब है "हाँ, यह संभव है"। आप पायथन कोड ले सकते हैं और CPython API का उपयोग करके इसे बराबर C कोड में संकलित करने का प्रयास कर सकते हैं। वास्तव में, एक Python2C प्रोजेक्ट हुआ करता था जो कि बस ऐसा ही करता था, लेकिन मैंने कई सालों में इसके बारे में नहीं सुना है (1.5 दिन में पायथन जब मैंने आखिरी बार देखा था।)

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


2

यह पायथन को मशीन कोड के लिए संकलित नहीं करता है। लेकिन पायथन कोड को कॉल करने के लिए एक साझा लाइब्रेरी बनाने की अनुमति देता है।

यदि आप जिस चीज की तलाश कर रहे हैं, वह निष्पादित सामान पर भरोसा किए बिना सी से पायथन कोड को चलाने का एक आसान तरीका है। आप अजगर कोड एम्बेडिंग एपीआई के लिए कुछ कॉल के साथ लिपटे अजगर कोड से एक साझा पुस्तकालय उत्पन्न कर सकता है । वैसे एप्लिकेशन एक साझा पुस्तकालय है, एक .so जिसे आप कई अन्य पुस्तकालयों / अनुप्रयोगों में उपयोग कर सकते हैं।

यहां एक सरल उदाहरण है जो एक साझा पुस्तकालय बनाता है, जिसे आप सी कार्यक्रम के साथ जोड़ सकते हैं। साझा पुस्तकालय पायथन कोड निष्पादित करता है।

अजगर फ़ाइल को निष्पादित किया जाएगा pythoncalledfromc.py:

# -*- encoding:utf-8 -*-
# this file must be named "pythoncalledfrom.py"

def main(string):  # args must a string
    print "python is called from c"
    print "string sent by «c» code is:"
    print string
    print "end of «c» code input"
    return 0xc0c4  # return something

आप इसके साथ कोशिश कर सकते हैं python2 -c "import pythoncalledfromc; pythoncalledfromc.main('HELLO')। यह उत्पादन होगा:

python is called from c
string sent by «c» code is:
HELLO
end of «c» code input

साझा पुस्तकालय निम्नलिखित द्वारा परिभाषित किया जाएगा callpython.h:

#ifndef CALL_PYTHON
#define CALL_PYTHON

void callpython_init(void);
int callpython(char ** arguments);
void callpython_finalize(void);

#endif

संबद्ध callpython.cहै:

// gcc `python2.7-config --ldflags` `python2.7-config --cflags` callpython.c -lpython2.7 -shared -fPIC -o callpython.so

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <python2.7/Python.h>

#include "callpython.h"

#define PYTHON_EXEC_STRING_LENGTH 52
#define PYTHON_EXEC_STRING "import pythoncalledfromc; pythoncalledfromc.main(\"%s\")"


void callpython_init(void) {
     Py_Initialize();
}

int callpython(char ** arguments) {
  int arguments_string_size = (int) strlen(*arguments);
  char * python_script_to_execute = malloc(arguments_string_size + PYTHON_EXEC_STRING_LENGTH);
  PyObject *__main__, *locals;
  PyObject * result = NULL;

  if (python_script_to_execute == NULL)
    return -1;

  __main__ = PyImport_AddModule("__main__");
  if (__main__ == NULL)
    return -1;

  locals = PyModule_GetDict(__main__);

  sprintf(python_script_to_execute, PYTHON_EXEC_STRING, *arguments);
  result = PyRun_String(python_script_to_execute, Py_file_input, locals, locals);
  if(result == NULL)
    return -1;
  return 0;
}

void callpython_finalize(void) {
  Py_Finalize();
}

आप इसे निम्न कमांड के साथ संकलित कर सकते हैं:

gcc `python2.7-config --ldflags` `python2.7-config --cflags` callpython.c -lpython2.7 -shared -fPIC -o callpython.so

एक फ़ाइल बनाएं जिसका नाम callpythonfromc.cनिम्नलिखित है:

#include "callpython.h"

int main(void) {
  char * example = "HELLO";
  callpython_init();
  callpython(&example);
  callpython_finalize();
  return 0;
}

इसे संकलित करें और चलाएं:

gcc callpythonfromc.c callpython.so -o callpythonfromc
PYTHONPATH=`pwd` LD_LIBRARY_PATH=`pwd` ./callpythonfromc

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

Nuitka सहायक हो सकता है।

इसके अलावा सुंबा है, लेकिन वे दोनों जो आप चाहते हैं वह करने का लक्ष्य नहीं रखते हैं। पायथन कोड से C हेडर बनाना संभव है, लेकिन केवल तभी जब आप निर्दिष्ट करें कि पायथन प्रकारों को C प्रकारों में कैसे परिवर्तित किया जाए या उस जानकारी का अनुमान लगाया जा सकता है। अजगर खगोल विज्ञानी के लिए अजगर एस्ट्रोइड देखें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.