मैं हमेशा जानता था कि पायथन के फायदों में से एक सी कोड के सबसे निरोधात्मक टुकड़ों को फिर से लिखने और अप्राप्य व्याख्या की गई भाषा ऊंचाइयों पर कार्यक्रम की गति को बढ़ाने की क्षमता है। लेकिन मैंने कभी इसे खुद करने की कोशिश नहीं की, क्योंकि यह बहुत जटिल था। इस लेख को पढ़ने के बाद मुझे अब ऐसा नहीं लगता।
Ctypes से परिचित प्रोग्रामर को यहां कुछ भी दिलचस्प होने की संभावना नहीं है, लेकिन शुरुआती लोगों के लिए, मैं बिल्ली के लिए पूछता हूं।
Ctypes बाहरी पुस्तकालयों से कार्यों के आयात के लिए पायथन तंत्र है।
% टाइमिट -
आईपीथॉन शेल मैजिक फ़ंक्शन जो पायथन में एक अभिव्यक्ति के निष्पादन समय को मापता है
Ctypes बढ़िया है! आइए एक छोटे से भोज उदाहरण से शुरू करें: एक निश्चित सीमा में संख्याओं को समेटें।
यहां पायथन में इस फ़ंक्शन का कार्यान्वयन है
def sumrange(arg): return sum(xrange(arg))
बहुत बढ़िया! लेकिन क्या होगा अगर हम संख्याओं को वास्तव में बड़ी संख्या में संक्षेपित करने की कोशिश करते हैं, उदाहरण के लिए 0 से 10 ** 8 (यानी 100,000,000)
In [2]: %timeit sumrange(10**2) 1000000 loops, best of 3: 1.53 us per loop In [3]: %timeit sumrange(10**8) 1 loops, best of 3: 9.77 s per loop In [4]: %timeit sumrange(10**9) 1 loops, best of 3: 97.8 s per loop
अब और मजा नहीं आया। चलो कुछ और कोशिश करते हैं:
def sumrange2(arg): x = i = 0 while i < arg: x += i i += 1 return x
इसका क्या आएगा?
In [10]: %timeit sumrange2(10**2) 100000 loops, best of 3: 10.5 us per loop In [11]: %timeit sumrange2(10**8) 1 loops, best of 3: 18.5 s per loop
वाह ... बहुत बुरा ... इस बार मैंने 10 ** 9 भी नहीं जीते।
तो हम निष्पादन को कैसे गति देते हैं? बस गणितीय अनुकूलन की पेशकश न करें ... हम कंप्यूटर की नई दुनिया में हैं! (
मूल में: गणित के गुर नहीं सुझाएंगे ... यह कंप्यूटिंग की नई दुनिया है! )
हां, मुझे पता है कि एल्गोरिथ्म की जटिलता एक स्थिर है और यह तर्क के मूल्य पर निर्भर नहीं करता है, n * (n + 1) / 2। लेकिन लेख इसके लिए समर्पित नहीं है।
Ctypes के बारे में क्या?
#include <stdio.h> unsigned long long sumrange(unsigned long long arg) { unsigned long long i, x; x = 0; for (i = 0; i < arg; i++) { x = x + i; } return x; }
Sumrange.c नाम से संकलित करें और संकलित करें (हम प्रयोग की शुद्धता के लिए अनुकूलन का उपयोग नहीं करेंगे):
$ gcc -shared -Wl,-install_name,sumrange.so -o sumrange.so -fPIC sumrange.c
अजगर में आयात क्या हुआ:
import ctypes sumrange_ctypes = ctypes.CDLL('./sumrange.so').sumrange sumrange_ctypes.restype = ctypes.c_ulonglong sumrange_ctypes.argtypes = ctypes.c_ulonglong,
और ऑस्कर मिलता है ...
In [15]: %timeit sumrange_ctypes(10**2) 1000000 loops, best of 3: 1.28 us per loop In [16]: %timeit sumrange_ctypes(10**8) 1 loops, best of 3: 381 ms per loop In [17]: %timeit sumrange_ctypes(10**9) 1 loops, best of 3: 3.79 s per loop In [18]: %timeit sumrange_ctypes(10**10) 1 loops, best of 3: 37.8 s per loop
सारांश सारांश:
| १० ** २ | १० ** 8 | १० ** ९ | १० ** १० |
---|
शुद्ध पायथन विधि # 1 | 1.53 μs है | 9.77 एस | 97.8 एस | - |
शुद्ध अजगर विधि 2 | 10.5 μs है | 18.5 एस | - | - |
ctypes | 1.28 μ | 381 मि | 3.79 एस | 37.8 एस |
राक्षसी प्रदर्शन को बढ़ावा!
Node.js हैकर्स के लिए, ctypes समतुल्य है - FFI (फॉरेन फंक्शन इंटरफ़ेस):
github.com/rbranson/node-ffi