शीर्ष सर्वर-साइड स्विफ्ट फ्रेमवर्क बनाम Node.js के लिए बेंचमार्क

7 अक्टूबर को संपादित करें: मेरा अनुसरण करें चेकआउट करें: लिनक्स के लिए बेंचमार्क (उबंटू)

परिचय

हाल ही में मैं सर्वर-साइड स्विफ्ट में काम कर रहा था, और मुझसे सवाल पूछा गया था:

"सर्वर साइड स्विफ्ट Node.js को हरा सकता है?"

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

शीर्ष सर्वर साइड स्विफ्ट चौखटे

लेखन के समय, शीर्ष सर्वर-साइड स्विफ्ट फ्रेमवर्क (गिथहब पर सितारों के क्रम में सूचीबद्ध) हैं:

  • बिल्कुल सही 957,956
  • वाष्प ️5,183
  • किटुरा ️4,017
  • Zewo ️1,186

इस पद का संगठन

यह दस्तावेज़ निम्नलिखित तरीके से निर्धारित किया गया है:

  • यह त्वरित परिचय
  • परिणाम सारांश
  • क्रियाविधि
  • विस्तृत परिणाम
  • निष्कर्ष और अंतिम नोट्स

परिणाम सारांश

निम्नलिखित प्राथमिक बेंचमार्क का एक त्वरित सारांश है, और मैं यहां यह कहूंगा:

कोई फर्क नहीं पड़ता कि व्यक्तिगत रैंकिंग, इन सभी रूपरेखाओं ने अविश्वसनीय रूप से अच्छा प्रदर्शन किया, स्विफ्ट ने लगातार नोड.जे को हराया, और वे सभी के साथ काम करने में बहुत मज़ा आया।
इस छवि को सुधार के साथ 1 सितंबर, 2016 को अपडेट किया गया था

कार्यप्रणाली और नोट्स

ब्लॉग और JSON का उपयोग क्यों करें?

ज्यादातर बस, ब्लॉग "हैलो, दुनिया!" से अधिक है, और JSON एक बहुत ही सामान्य उपयोग मामला है। अच्छे बेंचमार्क को प्रत्येक फ्रेमवर्क पर समान लोड की आवश्यकता होती है, और इसे थोड़ा और लोड करने की आवश्यकता होती है जो स्क्रीन पर दो शब्दों को प्रिंट करता है।

वही चीजें रखना

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

गंभीर अंतर

सर्वर-साइड स्विफ्ट फ्रेमवर्क के बीच ध्यान देने के लिए कुछ सूक्ष्म अंतर हैं।

  • किट्टुरा और ज़ेवो दोनों के निर्माण के मुद्दे हैं यदि उनके पूर्ण फ़ाइल पथ में कोई रिक्त स्थान हैं। Xcode में किसी भी ढांचे में निरपेक्ष फ़ाइल पथों में रिक्त स्थान के साथ निर्माण के मुद्दे भी हैं।
  • Zewo 05–09-एक स्विफ्ट स्नैपशॉट का उपयोग कर रहा है, जिसका अर्थ है कि इसे रिलीज मोड में निर्माण करने में परेशानी होती है और इसे डिबग मोड में चलाना पड़ता है। Zewo के सभी परीक्षण Zewo के साथ किए गए और इस कारण से डिबग मोड (बिना रिलीज़ ऑप्टिमाइज़ेशन) के चल रहे थे।
  • स्टेटिक फाइल हैंडलिंग सर्वर-साइड स्विफ्ट फ्रेमवर्क के बीच बहस का एक बिंदु है। वाष्प और Zewo दोनों Nginx को स्टैटिक फाइल हैंडलिंग के लिए प्रॉक्सी के रूप में उपयोग करने की सलाह देते हैं, फिर बैकएंड के लिए प्रोसेसिंग पावर के रूप में उसके पीछे फ्रेमवर्क को डालते हैं। परफेक्ट उनके हैंडलर में निर्मित का उपयोग करने का सुझाव देता है, और मैंने इस विषय पर अपने स्वयं के विचारों के बारे में आईबीएम पर कोई टिप्पणी नहीं देखी है। चूँकि यह अध्ययन इस बात के बारे में नहीं था कि Nginx जैसे स्थापित सर्वर अनुप्रयोगों के साथ फ्रेमवर्क कितनी अच्छी तरह काम करते हैं, स्थिर फ़ाइल हैंडलिंग प्रत्येक फ्रेमवर्क के साथ मूल रूप से उपयोग की जाती थी। यदि आप इसे ध्यान में रखते हुए बनाना चाहते हैं, तो आप वाष्प और Zewo दोनों में बेहतर प्रदर्शन प्राप्त कर सकते हैं। यह भी एक माध्यमिक कारण है कि मैंने JSON परीक्षण शामिल किया है।
  • [1 सितंबर को अद्यतन परिणामों के साथ जोड़ा गया] Zewo एक एकल थ्रेडेड एप्लिकेशन है। आप उपलब्ध सीपीयू प्रति के एक उदाहरण को चलाकर अतिरिक्त प्रदर्शन प्राप्त कर सकते हैं, क्योंकि वे मल्टी थ्रेड मॉडल के बजाय समवर्ती का अनुसरण करते हैं। इस अध्ययन के प्रयोजनों के लिए, प्रत्येक एप्लिकेशन का केवल एक उदाहरण चलाया गया था।
  • Toolchains। प्रत्येक रूपरेखा Apple से एक अलग विकास स्नैपशॉट उपकरण का निर्माण कर रही है। अंतिम परीक्षण के समय वे / थे:
     
    - विकास- SNAPSHOT-2016-08-24- के लिए बिल्कुल सही
    - भाप और कितूरा के लिए विकास-स्नैपशॉट-2016-07–25-
    - विकास- SNAPSHOT-2016-05–09-Zewo के लिए
  • चल रहे रिलीज के लिए वाष्प में एक विशेष वाक्यविन्यास है। यदि आप केवल बाइनरी निष्पादित करते हैं, तो आप कुछ अतिरिक्त कंसोल लॉगिंग प्राप्त करने जा रहे हैं जो विकास और डीबगिंग प्रक्रिया में मदद करने के लिए है। वह थोड़ा ओवरहेड है। वाष्प को रिलीज़ मोड में चलाने के लिए आपको जोड़ना होगा
--env = उत्पादन

निष्पादन योग्य है। अर्थात।

.build / रिलीज / ऐप --env = उत्पादन
  • [1 सितंबर को अद्यतन परिणामों के साथ जोड़ा गया] जब आप Zewo के साथ काम कर रहे हों, भले ही आप 05–09-टूलकिन पर रिलीज़ मोड में तेज़ी से निर्माण नहीं कर सकते, आप इन तर्कों को पारित करके कुछ रिलीज़ मोड अनुकूलन जोड़ सकते हैं:
स्विफ्ट बिल्ड -Xswiftc -O
  • Node.js / Express निर्माण नहीं करता है, और न ही यह डिबग / रिलीज़ के बीच अंतर करता है
  • वाष्प के डिफ़ॉल्ट मिडलवेयर में स्टेटिक फ़ाइल हैंडलिंग शामिल है। यदि आप स्थिर फ़ाइलों का उपयोग नहीं कर रहे हैं और गति के लिए अनुकूलित करना चाहते हैं, तो आपको अवश्य शामिल करना चाहिए (जैसा कि मैंने VaporJSON में किया था):
drop.middleware = []

Node.js / एक्सप्रेस क्यों?

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

ब्लॉग का विकास करना

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

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

होस्टिंग और पर्यावरण

पर्यावरण में किसी भी अंतर को कम करने के लिए, मैंने 2012 मैक मिनी लिया और इसे एल कैपिटान (10.11.6) की एक साफ स्थापना दी। उसके बाद, मैंने Xcode 8 बीटा 6 को डाउनलोड और इंस्टॉल किया, और अपने कमांड लाइन टूल्स को Xcode 8 पर सेट किया। वहां से मैंने swiftenv को स्थापित किया, आवश्यक स्नैपशॉट्स को स्थापित किया, रेपो को क्लोन किया, और प्रत्येक ब्लॉग को सफाई से बनाया, फिर से रिलीज़ मोड में जहां मुमकिन। मैं एक बार में एक से अधिक नहीं भागा, और प्रत्येक को परीक्षणों के बीच रोक दिया गया और पुनः आरंभ किया गया। परीक्षण सर्वर चश्मा हैं:

विकास के लिए, मैं एक 2015 आरएमबीपी का उपयोग करता हूं। मैंने यहां बिल्ड टाइम टेस्ट्स चलाए, क्योंकि यह मेरी वास्तविक जीवन की विकास मशीन है और इसने सबसे अधिक समझ में आता है। मैंने बेंचमार्क प्राप्त करने के लिए wrk का उपयोग किया, और मैंने मशीनों के बीच वज्र 2 केबल का उपयोग करके एक वज्र पुल पर किया। वज्र पुल का उपयोग करना सुनिश्चित करता है कि आपके पास बैंडविड्थ की अविश्वसनीय मात्रा है और आप अपने राउटर की सीमाओं को हाथ में लिए कार्य के बजाय बेंचमार्किंग नहीं कर रहे हैं। यह एक मशीन पर ब्लॉगों की सेवा करने के लिए और लोड को उत्पन्न करने के लिए एक अलग, अधिक शक्तिशाली मशीन का उपयोग करने के लिए अधिक विश्वसनीय है, यह सुनिश्चित करते हुए कि आप सर्वर पर हावी होने में सक्षम हैं, ताकि आप सुनिश्चित कर सकें कि यह एक सीमा नहीं है। यह आपको एक सुसंगत परीक्षण वातावरण भी देता है, इसलिए मैं कह सकता हूं कि प्रत्येक ब्लॉग एक ही हार्डवेयर और एक ही स्थिति में चलाया गया था। जिज्ञासु के लिए, मेरी मशीन के चश्मे हैं:

बेंचमार्किंग नोट्स

बेंचमार्किंग के लिए, मैंने चार धागे के साथ दस मिनट के परीक्षण का उपयोग करने का निर्णय लिया, प्रत्येक में 20 कनेक्शन थे। चार सेकंड परीक्षण नहीं है। दस मिनट बहुत से डेटा प्राप्त करने के लिए एक उचित समय सीमा है, और चार थ्रेड्स पर 20 कनेक्शन चलाना ब्लॉगों के लिए एक भारी भार है, लेकिन ब्रेकिंग लोड नहीं है।

सोर्स कोड

यदि आप परियोजनाओं के लिए स्रोत कोड का पता लगाना चाहते हैं या अपना स्वयं का परीक्षण करना चाहते हैं, तो मैंने पाया कि एक भंडार में परीक्षण के लिए उपयोग किए गए कोड को समेकित किया गया है:

https://github.com/rymcol/Server-Side-Swift-Benchmarking

विस्तृत परिणाम

निर्माण समय

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

क्या चलाया गया था

प्रत्येक ढांचे के लिए,

Swift build --clean = dist

और फिर

समय तेजी से निर्माण

चलाए गए, जिसके बाद दूसरा परीक्षण किया गया

स्विफ्ट बिल्ड - क्लीयन

फिर:

समय तेजी से निर्माण

यह कारक एसपीएम के साथ निर्भरता को खींचने सहित एक पूर्ण निर्माण, साथ ही साथ पहले से डाउनलोड की गई निर्भरता के साथ एक नियमित, साफ निर्माण भी शामिल है।

इसे कैसे चलाया गया

यह मेरे स्थानीय 2015 आरएमबीपी पर चलाया गया था और बिल्ड सभी को डिबग मोड में किया गया था, क्योंकि लिफ्ट सॉफ्टवेयर विकसित करते समय यह सामान्य प्रक्रिया है।

समय परिणाम बनाएँ

स्मृति उपयोग

दूसरी चीज जो मैंने देखी, वह थी लोड के तहत प्रत्येक फ्रेमवर्क की मेमोरी फुटप्रिंट।

क्या था रन

पहला - मेमोरी फ़ुटप्रिंट शुरू करना (बस प्रक्रिया को देखा)
2 - मेरे परीक्षण सर्वर पर प्रक्रिया की पीक मेमोरी उपयोग का उपयोग:

wrk -d 1m -t 4 -c 10

3 - दूसरे परीक्षण का दोहराव:

wrk -d 1m -t 8 -c 100

यह कैसा रन था

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

मेमोरी उपयोग के परिणाम

धागा उपयोग

तीसरी चीज जो मैंने देखी, वह लोड के तहत प्रत्येक ढांचे का धागा उपयोग था।

क्या था रन

पहला - थ्रेड्स शुरू करना (बस प्रक्रिया को घूरना)
2 - पीक थ्रेड का उपयोग करके मेरे परीक्षण सर्वर पर प्रक्रिया का उपयोग:

wrk -d 1m -t 4 -c 10

यह कैसा रन था

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

इन परिणामों के बारे में एक नोट

इस श्रेणी में कोई "जीत" नहीं है। कई अनुप्रयोग थ्रेड को अलग तरह से मानते हैं, और ये फ्रेमवर्क अपवाद नहीं हैं। उदाहरण के लिए, Zewo एक एकल थ्रेडेड एप्लिकेशन है, और यह कभी भी एक से अधिक का उपयोग नहीं करेगा (संपादित करें: बिना समवर्ती कॉन्फ़िगरेशन के प्रत्येक CPU पर इसे चलाने के लिए आपके हस्तक्षेप के बिना)। दूसरी ओर, परफेक्ट, प्रति उपलब्ध CPU का उपयोग करेगा। वाष्प एक प्रति कनेक्शन मॉडल का उपयोग करेगा। जैसे, इस ग्राफ को इस तरह से डिज़ाइन किया गया था कि भार के तहत थ्रेड्स में स्पाइक्स आसानी से दिखाई देते हैं, क्योंकि वे दोनों ग्राफ़ में समान क्रम में हैं।

धागा उपयोग के परिणाम

ब्लॉग बेंचमार्क

पहला बेंचमार्क प्रत्येक में / ब्लॉग मार्ग है, जो एक पेज है जो प्रत्येक अनुरोध के लिए 5 यादृच्छिक छवियां और नकली ब्लॉग पोस्ट देता है।

क्या था रन

wrk -d 10m -t 4 -c 20 http://169.254.237.101:(PORT)/blog

मेरे rMBP से मेरे वज्र पुल पर प्रत्येक ब्लॉग के लिए चलाया गया था।

यह कैसा रन था

मेमोरी टेस्टिंग के साथ, प्रत्येक फ्रेम को रिलीज़ मोड में चलाया गया जहाँ संभव हो, और प्रत्येक परीक्षण से पहले रोका और पुनः आरंभ किया गया। सर्वर पर किसी भी समय केवल एक फ्रेमवर्क चल रहा था। पर्यावरण को यथासंभव समान रखने के लिए परीक्षण के दौरान दोनों मशीनों पर सभी गतिविधि को न्यूनतम बनाया गया था।

परिणाम

इस छवि को सुधार के साथ 1 सितंबर, 2016 को अपडेट किया गया थाइस छवि को सुधार के साथ 1 सितंबर, 2016 को अपडेट किया गया था

JSON बेंचमार्क

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

क्या था रन

wrk -d 10m -t 4 -c 20 http://169.254.237.101:(PORT)/json

प्रत्येक JSON परियोजना के लिए चलाया गया था।

यह कैसा रन था

अन्य परीक्षणों की तरह, प्रत्येक फ्रेम को रिलीज़ मोड में चलाया गया जहाँ संभव हो, और प्रत्येक परीक्षण से पहले रोका और पुनः आरंभ किया गया। सर्वर पर किसी भी समय केवल एक फ्रेमवर्क चल रहा था। पर्यावरण को यथासंभव समान रखने के लिए परीक्षण के दौरान दोनों मशीनों पर सभी गतिविधि को न्यूनतम बनाया गया था।

परिणाम

इस छवि को सुधार के साथ 1 सितंबर, 2016 को अपडेट किया गया थाइस छवि को सुधार के साथ 1 सितंबर, 2016 को अपडेट किया गया था

निष्कर्ष

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

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

उलझना

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

परफेक्ट: वेबसाइट | जीठब | सुस्त | Gitter
वाष्प: वेबसाइट | जीठब | ढीला
कितूरा: वेबसाइट | जीठब | Gitter
Zewo: वेबसाइट | जीठब | ढीला

संपर्क में रहो

यदि आप कनेक्ट करना चाहते हैं, तो आप ट्विटर पर मेरे @rymcol तक पहुंच सकते हैं।

डिस्क्लोजर मुझे लगा कि जरूरी थे: एड्यूज के अनुकूलन के बाद कुछ डेटा को सही करने के लिए एडिट्स को 1 सितंबर, 2016 को जोड़ा गया था, जोवो के लिए `स्विफ्ट बिल्ड -सी रिलीज़` के लिए वैकल्पिक विधि का उपयोग करके किए गए थे। परफेक्टली सॉफ्ट इंक ने स्विफ्ट की शक्ति को बढ़ावा देने के लिए, मेरे लिए इस अध्ययन को निधि देने पर सहमति व्यक्त की। मैं परफेक्ट एंड वैपोर के लिए जीथब टीमों पर भी हूँ, हालाँकि मैं न तो किसी का कर्मचारी हूँ, और न ही मेरी राय उनके बारे में बताती है। जैसा कि मैंने सभी चार प्लेटफार्मों में विकसित किया है, मैंने निष्पक्ष रहने के लिए अपनी पूरी कोशिश की है, और मैं वास्तव में परिणाम देखने के लिए उत्सुक था। इस अध्ययन के लिए सभी कोड युवा रूप से उपलब्ध हैं, कृपया इसे जांचने के लिए स्वतंत्र महसूस करें या कुछ परीक्षणों को दोहराएं और इसे अपने लिए सत्यापित करें!