अपना एगो ताजा जॉब इंटरव्यू के बाद हमरा एह बात के अहसास भइल कि जवना कंपनी खातिर हम आवेदन कइले रहीं ऊ अबहियों लारावेल के इस्तेमाल करत बिया जवन एगो पीएचपी फ्रेमवर्क ह जवना के हम करीब एक दशक पहिले कोशिश कइले रहीं. ओह घरी खातिर ई सभ्य रहे बाकिर अगर तकनीक आ फैशन में एके जइसन स्थिरता बा त ऊ बा शैली आ अवधारणा में लगातार बदलाव आ फेर से उभरल. अगर रउरा जावास्क्रिप्ट प्रोग्रामर हईं त शायद एह पुरान मजाक से परिचित बानी
प्रोग्रामर 1: "हमरा ई नया जावास्क्रिप्ट फ्रेमवर्क पसंद नइखे!"
प्रोग्रामर 2: "चिंता करे के जरूरत नइखे। बस छह महीना इंतजार करीं आ एकरा के बदले खातिर एगो अउरी होखी!"
जिज्ञासा से हम तय कइनी कि जब हमनी का पुरान आ नया के परीक्षण में डाल देनी जा त ठीक से का होला. बेशक, वेब बेंचमार्क आ दावा से भरल बा, जवना में से सबसे लोकप्रिय शायद... इहाँ टेकएमपावर वेब फ्रेमवर्क बेंचमार्क बा . हमनी के आज हालांकि ओतना जटिल काम नईखी करे वाला। हमनी का दुनु बात के बढ़िया आ सरल राखब जा जेहसे कि ई लेख ना बदल जाव युद्ध आ शांति के बात कइल जाव , आ कि जबले रउरा पढ़ के खतम हो जाईं तबले रउरा जागल रहे के तनी मौका मिल जाई. आम चेतावनी लागू होला: हो सकेला कि ई रउरा मशीन पर एके जइसन काम ना करे, अलग अलग सॉफ्टवेयर संस्करण प्रदर्शन पर असर डाल सकेला आ श्रोडिंजर के बिल्ली असल में एगो ज़ोंबी बिल्ली बन गइल जवन ठीक एके समय में आधा जिंदा आ आधा मर गइल रहे.
एह परीक्षण खातिर हम अपना लैपटॉप के इस्तेमाल एगो क्षुद्र i5 से लैस करब जवना में मंजारो लिनक्स चलत बा जइसन कि एहिजा देखावल गइल बा.
╰─➤ uname -a
Linux jimsredmi 5.10.174-1-MANJARO #1 SMP PREEMPT Tuesday Mar 21 11:15:28 UTC 2023 x86_64 GNU/Linux
╰─➤ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 126
model name : Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz
stepping : 5
microcode : 0xb6
cpu MHz : 990.210
cache size : 6144 KB
हमनी के कोड में हर अनुरोध खातिर तीन गो सरल काम होई:
ऊ कवन बेवकूफी भरल परीक्षा ह, रउरा पूछ सकीलें? खैर, अगर रउआ एह पन्ना खातिर नेटवर्क अनुरोध देखब त रउआ एगो अइसन पन्ना देखब जवना के नाम sessionvars.js बा जवन ठीक वइसने काम करेला।
रउआँ देखत बानी कि आधुनिक वेब पन्ना जटिल जीव हवें आ एकर एगो आम काम जटिल पन्ना सभ के कैश कइल होला ताकि डेटाबेस सर्वर पर अतिरिक्त लोड ना होखे।
अगर हमनी के हर बेर जब कवनो प्रयोगकर्ता अनुरोध करेला त कवनो जटिल पन्ना के दोबारा रेंडर कर देनी जा त हमनी के प्रति सेकंड लगभग 600 उपयोगकर्ता के ही सेवा दे सकेनी जा।
╰─➤ wrk -d 10s -t 4 -c 100 http://127.0.0.1/system/index.en.html
Running 10s test @ http://127.0.0.1/system/index.en.html
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 186.83ms 174.22ms 1.06s 81.16%
Req/Sec 166.11 58.84 414.00 71.89%
6213 requests in 10.02s, 49.35MB read
Requests/sec: 619.97
Transfer/sec: 4.92MB
बाकिर अगर हमनी के एह पन्ना के स्थिर एचटीएमएल फाइल के रूप में कैश कर के Nginx के जल्दी से विंडो से बाहर यूजर के टॉस करे दीं जा त हमनी के प्रति सेकंड 32,000 यूजर के सेवा दे सकेनी जा, जवना से परफॉर्मेंस 50x के कारक बढ़ सकेला।
╰─➤ wrk -d 10s -t 4 -c 100 http://127.0.0.1/system/index.en.html
Running 10s test @ http://127.0.0.1/system/index.en.html
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 3.03ms 511.95us 6.87ms 68.10%
Req/Sec 8.20k 1.15k 28.55k 97.26%
327353 requests in 10.10s, 2.36GB read
Requests/sec: 32410.83
Transfer/sec: 238.99MB
स्थिर index.en.html ऊ हिस्सा हवे जे सभका लगे जाला आ sessionvars.js में खाली ऊ हिस्सा भेजल जाला जे प्रयोगकर्ता के हिसाब से अलग होखे लें। एहसे ना खाली डेटाबेस के लोड कम हो जाला आ हमनी के यूजर्स खातिर बेहतर अनुभव पैदा हो जाला बलुक क्वांटम संभावना भी कम हो जाला कि जब क्लिंगन हमला करीहें त हमनी के सर्वर वार्प कोर ब्रीच में अनायास वाष्पित हो जाई.
हर फ्रेमवर्क खातिर वापस कइल कोड के एगो सरल आवश्यकता होखी: प्रयोगकर्ता के ई देखाईं कि ऊ केतना बेर पन्ना के रिफ्रेश कइले बा आ ई कह के कि ऊ "गणना x बा"। चीजन के सरल राखे खातिर हमनी का फिलहाल रेडिस कतार, कुबेरनेट्स घटक, भा एडब्ल्यूएस लैम्ब्डा से दूर रहब जा.
हर यूजर के सत्र डेटा के पोस्टग्रेएसक्यूएल डेटाबेस में सेव कइल जाई।
आ हर परीक्षण से पहिले एह डेटाबेस टेबल के काट दिहल जाई.
सरल लेकिन प्रभावी बा पफेरा के आदर्श वाक्य... वैसे भी सबसे गहिराह समय रेखा से बाहर...
ठीक बा, त अब आखिरकार हमनी के हाथ गंदा करे के काम शुरू क सकेनी जा। हमनी का लारावेल खातिर सेटअप छोड़ देब जा काहे कि ई संगीतकार आ कारीगरन के एगो झुंड भर ह कमांड के बा।
सबसे पहिले हमनी के आपन डेटाबेस सेटिंग .env फाइल में सेटअप करब जा
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=sessiontest
DB_USERNAME=sessiontest
DB_PASSWORD=sessiontest
एकरा बाद हमनी के एगो फॉलबैक रूट सेट करब जा जवन हर रिक्वेस्ट के हमनी के कंट्रोलर के भेज देला।
Route::fallback(SessionController::class);
आ गिनती देखावे खातिर कंट्रोलर सेट करीं. लारावेल, डिफ़ॉल्ट रूप से, डेटाबेस में सत्र सभ के संग्रहीत करे ला। एकरा अलावे एहमें... session()
फंक्शन के हमनी के सत्र डेटा के संगे इंटरफेस करे खातिर, एहसे बस हमनी के पेज के रेंडर करे खाती कोड के एक-दु लाइन के जरूरत रहे।
class SessionController extends Controller
{
public function __invoke(Request $request)
{
$count = session('count', 0);
$count += 1;
session(['count' => $count]);
return 'Count is ' . $count;
}
}
php-fpm आ Nginx सेट कइला के बाद हमनी के पेज काफी बढ़िया लागत बा...
╰─➤ php -v
PHP 8.2.2 (cli) (built: Feb 1 2023 08:33:04) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.2, Copyright (c) Zend Technologies
with Xdebug v3.2.0, Copyright (c) 2002-2022, by Derick Rethans
╰─➤ sudo systemctl restart php-fpm
╰─➤ sudo systemctl restart nginx
कम से कम जब तक हमनी के असल में टेस्ट के रिजल्ट ना देखब जा...
PHP/Laravel
╰─➤ wrk -d 10s -t 4 -c 100 http://127.0.0.1
Running 10s test @ http://127.0.0.1
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.08s 546.33ms 1.96s 65.71%
Req/Sec 12.37 7.28 40.00 56.64%
211 requests in 10.03s, 177.21KB read
Socket errors: connect 0, read 0, write 0, timeout 176
Requests/sec: 21.04
Transfer/sec: 17.67KB
ना, ऊ कवनो टाइपो ना ह. हमनी के परीक्षण मशीन एगो जटिल पन्ना के रेंडर करे में 600 अनुरोध प्रति सेकंड से... से 21 अनुरोध प्रति सेकंड "गणना 1 बा"
त का गलत हो गइल? का हमनी के पीएचपी इंस्टॉलेशन में कुछ गलती बा? का php-fpm के साथ इंटरफेस करत घरी Nginx कवनो तरीका से धीमा हो रहल बा?
आईं एह पन्ना के शुद्ध पीएचपी कोड में दोबारा कइल जाव.
<?php
// ====================================================================
function uuid4()
{
return sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
}
// ====================================================================
function Query($db, $query, $params = [])
{
$s = $db->prepare($query);
$s->setFetchMode(PDO::FETCH_ASSOC);
$s->execute(array_values($params));
return $s;
}
// ********************************************************************
session_start();
$sessionid = 0;
if (isset($_SESSION['sessionid']))
{
$sessionid = $_SESSION['sessionid'];
}
if (!$sessionid)
{
$sessionid = uuid4();
$_SESSION['sessionid'] = $sessionid;
}
$db = new PDO('pgsql:host=127.0.0.1 dbname=sessiontest user=sessiontest password=sessiontest');
$data = 0;
try
{
$result = Query(
$db,
'SELECT data FROM usersessions WHERE uid = ?',
[$sessionid]
)->fetchAll();
if ($result)
{
$data = json_decode($result[0]['data'], 1);
}
} catch (Exception $e)
{
echo $e;
Query(
$db,
'CREATE TABLE usersessions(
uid TEXT PRIMARY KEY,
data TEXT
)'
);
}
if (!$data)
{
$data = ['count' => 0];
}
$data['count']++;
if ($data['count'] == 1)
{
Query(
$db,
'INSERT INTO usersessions(uid, data)
VALUES(?, ?)',
[$sessionid, json_encode($data)]
);
} else
{
Query(
$db,
'UPDATE usersessions
SET data = ?
WHERE uid = ?',
[json_encode($data), $sessionid]
);
}
echo 'Count is ' . $data['count'];
अब हमनी के 98 लाइन के कोड के इस्तेमाल ओह काम खातिर कइले बानी जा जवन लारावेल में चार लाइन कोड (आ कॉन्फ़िगरेशन के काम के पूरा गुच्छा) कइले रहे। (बेशक, अगर हमनी के सही तरीका से त्रुटि हैंडलिंग आ यूजर फेसिंग मैसेज करीं जा त ई लाइन के संख्या से लगभग दुगुना होई।) शायद हमनी के एकरा के 30 अनुरोध प्रति सेकंड तक बना सकेनी जा?
PHP/Pure PHP
╰─➤ wrk -d 10s -t 4 -c 100 http://127.0.0.1
Running 10s test @ http://127.0.0.1
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 140.79ms 27.88ms 332.31ms 90.75%
Req/Sec 178.63 58.34 252.00 61.01%
7074 requests in 10.04s, 3.62MB read
Requests/sec: 704.46
Transfer/sec: 369.43KB
वाह! लागत बा कि आखिरकार हमनी के पीएचपी इंस्टॉलेशन में कवनो गलती नइखे. शुद्ध पीएचपी संस्करण 700 अनुरोध प्रति सेकंड कर रहल बा।
अगर पीएचपी में कवनो गलती नइखे त शायद हमनी का लारावेल के गलत कॉन्फ़िगर कइले बानी जा?
कॉन्फ़िगरेशन के मुद्दा आ परफार्मेंस टिप्स खातिर वेब पर खोज कइला के बाद दू गो सभसे लोकप्रिय तकनीक कॉन्फिग के कैश कइल आ हर अनुरोध खातिर डेटा के रूट कइल रहल। एहसे हमनी के ओ लोग के सलाह लेके ए टिप्स के आजमा के देखब।
╰─➤ php artisan config:cache
INFO Configuration cached successfully.
╰─➤ php artisan route:cache
INFO Routes cached successfully.
कमांड लाइन पर सब कुछ बढ़िया लागत बा. आईं बेंचमार्क के दोबारा बनावल जाव.
╰─➤ wrk -d 10s -t 4 -c 100 http://127.0.0.1
Running 10s test @ http://127.0.0.1
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.13s 543.50ms 1.98s 61.90%
Req/Sec 25.45 13.39 50.00 55.77%
289 requests in 10.04s, 242.15KB read
Socket errors: connect 0, read 0, write 0, timeout 247
Requests/sec: 28.80
Transfer/sec: 24.13KB
खैर, हमनी के अब प्रदर्शन 21.04 से बढ़ा के 28.80 रिक्वेस्ट प्रति सेकंड क देले बानी जा, जवन कि लगभग 37% के नाटकीय उछाल बा! ई कवनो सॉफ्टवेयर पैकेज खातिर काफी प्रभावशाली होई... सिवाय एह बात के कि हमनी के अभी भी शुद्ध PHP संस्करण के अनुरोध के संख्या के 1/24वां हिस्सा ही कर रहल बानी जा।
अगर रउआँ सोचत बानी कि एह परीक्षण में कुछ गलती जरूर बा, त रउआँ के लुसिंडा पीएचपी फ्रेमवर्क के लेखक से बात करे के चाहीं। अपना टेस्ट रिजल्ट में उनुका... लुसिंडा लारावेल के पीटत बाड़ी एचटीएमएल अनुरोध खातिर 36x आ जेएसओएन अनुरोध खातिर 90x.
अपाचे अवुरी एनजीनक्स दुनो के संगे अपना मशीन प टेस्ट कईला के बाद हमरा उनुका प शक करे के कवनो कारण नईखे। लारावेल वाकई में न्यायसंगत बाड़े ऊ धीमा! पीएचपी अपने आप में ओतना खराब नईखे, लेकिन एक बेर जब आप हर अनुरोध में लारावेल जवन अतिरिक्त प्रोसेसिंग जोड़ता, ओकरा के जोड़ देनी, त हमरा 2023 में लारावेल के विकल्प के रूप में सिफारिश कईल बहुत मुश्किल हो जाला।
पीएचपी/वर्डप्रेस के खाता बा वेब पर मौजूद सगरी वेबसाइटन के लगभग 40% , जवन एकरा के अब तक के सबसे दबंग रूपरेखा बना देले बा। हालांकि निजी तौर प हमरा लागता कि लोकप्रियता के गुणवत्ता में बदलल जरूरी नईखे जतना कि हमरा अपना के अचानक से ओह असाधारण पेटू भोजन के बेकाबू आग्रह होखता दुनिया के सबसे लोकप्रिय रेस्तरां ह ... मैकडॉनल्ड्स के नाम से जानल जाला। चूँकि हमनी का शुद्ध पीएचपी कोड के परीक्षण कर चुकल बानी जा एहसे हमनी का खुद वर्डप्रेस के परीक्षण नइखीं करे वाला काहे कि वर्डप्रेस से जुड़ल कवनो चीज निस्संदेह ओह 700 अनुरोध प्रति सेकंड से कम होखी जवन हमनी का शुद्ध पीएचपी से देखले रहीं जा.
Django एगो अउरी लोकप्रिय ढाँचा हवे जे बहुत दिन से चल रहल बा। अगर रउआँ एकर इस्तेमाल पहिले भी कइले बानी त रउआँ शायद एकर शानदार डेटाबेस प्रशासन इंटरफेस के साथे-साथे बहुत प्यार से याद करत बानी कि हर चीज के ठीक ओइसने कॉन्फ़िगर कइल केतना परेशान करे वाला रहे जइसे रउआँ चाहत रहनी। देखल जाव कि 2023 में Django केतना बढ़िया काम करेला, खासकर के नया ASGI इंटरफेस के साथ जवन ऊ संस्करण 4.0 के रूप में जोड़ले बा।
डजांगो के सेटअप कइल लारावेल के सेटअप से उल्लेखनीय रूप से मिलत जुलत बा, काहें से कि ई दुनों ओह जमाना के रहलें जहाँ एमवीसी आर्किटेक्चर स्टाइलिश आ सही रहलें। हमनी के नीरस कॉन्फ़िगरेशन के छोड़ के सीधे व्यू सेटअप पर चलब जा।
from django.shortcuts import render
from django.http import HttpResponse
# =====================================================================
def index(request):
count = request.session.get('count', 0)
count += 1
request.session['count'] = count
return HttpResponse(f"Count is {count}")
चार लाइन के कोड उहे बा जवन लारावेल संस्करण के संगे बा। देखल जाव कि एकर प्रदर्शन कइसे होला.
╰─➤ python --version
Python 3.10.9
Python/Django
╰─➤ gunicorn --access-logfile - -k uvicorn.workers.UvicornWorker -w 4 djangotest.asgi
[2023-03-21 15:20:38 +0800] [2886633] [INFO] Starting gunicorn 20.1.0
╰─➤ wrk -d 10s -t 4 -c 100 http://127.0.0.1:8000/sessiontest/
Running 10s test @ http://127.0.0.1:8000/sessiontest/
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 277.71ms 142.84ms 835.12ms 69.93%
Req/Sec 91.21 57.57 230.00 61.04%
3577 requests in 10.06s, 1.46MB read
Requests/sec: 355.44
Transfer/sec: 148.56KB
355 अनुरोध प्रति सेकंड पर बिल्कुल खराब नइखे। इ शुद्ध पीएचपी संस्करण के मात्र आधा प्रदर्शन बा, लेकिन इ लारावेल संस्करण के 12 गुना भी बा। डजांगो बनाम लारावेल के मुकाबला बिल्कुल ना लउकत बा.
बड़का सबकुछ-सिंक-सिंक-सहित फ्रेमवर्क के अलावा, छोट-छोट फ्रेमवर्क भी बा जवन बस कुछ बेसिक सेटअप करेला जबकि बाकी के संभाले देला। एकर इस्तेमाल करे खातिर सबसे बढ़िया में से एगो बा फ्लास्क अवुरी एकर एएसजीआई समकक्ष क्वार्ट। हमार आपन पफेरापी ढाँचा के बा फ्लास्क के ऊपर बनल बा, एहसे हम एह बात से बढ़िया से परिचित बानी कि प्रदर्शन के बरकरार राखत काम पूरा कइल केतना आसान बा.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Session benchmark test
import json
import psycopg
import uuid
from flask import Flask, session, redirect, url_for, request, current_app, g, abort, send_from_directory
from flask.sessions import SecureCookieSessionInterface
app = Flask('pafera')
app.secret_key = b'secretkey'
dbconn = 0
# =====================================================================
@app.route('/', defaults={'path': ''}, methods = ['GET', 'POST'])
@app.route('/<path:path>', methods = ['GET', 'POST'])
def index(path):
"""Handles all requests for the server.
We route all requests through here to handle the database and session
logic in one place.
"""
global dbconn
if not dbconn:
dbconn = psycopg.connect('dbname=sessiontest user=sessiontest password=sessiontest')
cursor = dbconn.execute('''
CREATE TABLE IF NOT EXISTS usersessions(
uid TEXT PRIMARY KEY,
data TEXT
)
''')
cursor.close()
dbconn.commit()
sessionid = session.get('sessionid', 0)
if not sessionid:
sessionid = uuid.uuid4().hex
session['sessionid'] = sessionid
cursor = dbconn.execute("SELECT data FROM usersessions WHERE uid = %s", [sessionid])
row = cursor.fetchone()
count = json.loads(row[0])['count'] if row else 0
count += 1
newdata = json.dumps({'count': count})
if count == 1:
cursor.execute("""
INSERT INTO usersessions(uid, data)
VALUES(%s, %s)
""",
[sessionid, newdata]
)
else:
cursor.execute("""
UPDATE usersessions
SET data = %s
WHERE uid = %s
""",
[newdata, sessionid]
)
cursor.close()
dbconn.commit()
return f'Count is {count}'
जईसे कि आप देख सकत बानी कि फ्लास्क स्क्रिप्ट शुद्ध पीएचपी स्क्रिप्ट से छोट बा। हमरा लागत बा कि जवना भाषा के हम इस्तेमाल कइले बानी ओहमें से शायद पायथन टाइप कइल कीस्ट्रोक के मामिला में सबसे अधिका अभिव्यंजक भाषा बा. ब्रेसिज़ आ कोष्ठक के कमी, लिस्ट आ डिक्ट के समझ, आ सेमीकोलन के बजाय इंडेंटेशन के आधार पर ब्लॉकिंग पायथन के काफी सरल बनावे ला बाकी अपना क्षमता में शक्तिशाली बनावे ला।
दुर्भाग्य से पायथन भी सबसे धीमा सामान्य उद्देश्य भाषा हवे, बावजूद एकरा में केतना सॉफ्टवेयर लिखल गइल बा। उपलब्ध पायथन लाइब्रेरी सभ के संख्या समान भाषा सभ से लगभग चार गुना ढेर बा आ ई बहुत सारा डोमेन सभ के कवर करे ला, फिर भी केहू ई ना कह पाई कि पायथन NumPy नियर आला सभ के बाहर तेज बा आ ना ही परफार्मेंस करे वाला बा।
देखल जाव कि हमनी के फ्लास्क संस्करण के तुलना हमनी के पिछला ढाँचा से कइसे कइल जाला.
Python/Flask
╰─➤ gunicorn --access-logfile - -w 4 flasksite:app
[2023-03-21 15:32:49 +0800] [2856296] [INFO] Starting gunicorn 20.1.0
╰─➤ wrk -d 10s -t 4 -c 100 http://127.0.0.1:8000
Running 10s test @ http://127.0.0.1:8000
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 91.84ms 11.97ms 149.63ms 86.18%
Req/Sec 272.04 39.05 380.00 74.50%
10842 requests in 10.04s, 3.27MB read
Requests/sec: 1080.28
Transfer/sec: 333.37KB
हमनी के फ्लास्क स्क्रिप्ट असल में हमनी के शुद्ध पीएचपी संस्करण से तेज बा!
अगर रउआ एह से हैरान बानी त रउआ एहसास होखे के चाहीं कि हमनी के फ्लास्क ऐप आपन सभ इनिशियलाइजेशन आ कॉन्फ़िगरेशन तब करेला जब हमनी के गुनिकॉर्न सर्वर शुरू करेनी जा, जबकि पीएचपी हर बेर जब कवनो नया अनुरोध आवेला त स्क्रिप्ट के दोबारा निष्पादित करेला ;s फ्लास्क के बराबर बा जे ऊ युवा, उत्सुक टैक्सी ड्राइवर हवे जे पहिलहीं से गाड़ी स्टार्ट कर चुकल बा आ सड़क के बगल में इंतजार करत बा, जबकि पीएचपी ऊ बूढ़ ड्राइवर हवे जे अपना घर में रह के फोन आवे के इंतजार करत रहेला आ तबहिए गाड़ी चलावेला रउरा के उठावे खातिर ओवर हो गइल बा. पुरान स्कूल के आदमी होखला के नाते आ ओह जमाना से आवत जब पीएचपी सादा एचटीएमएल आ एसएचटीएमएल फाइल में एगो अद्भुत बदलाव रहे, एह बात के एहसास कइल तनी दुखद बा कि केतना समय बीत गइल बा, बाकिर डिजाइन के अंतर सचहूँ पीएचपी खातिर मुश्किल बना देला पायथन, जावा, आ नोड.जेएस सर्वर से मुकाबला करेला जे बस मेमोरी में रहेला आ जुगाड़ू के फुर्तीला आसानी से अनुरोध के संभालेला.
फ्लास्क अब तक के हमनी के सबसे तेज फ्रेमवर्क हो सकता, लेकिन असल में इ बहुत पुरान सॉफ्टवेयर ह। पायथन समुदाय एक दू साल पहिले नया एसिक्रोनस एएसजीआई सर्वर पर स्विच कइले रहे, आ बेशक, हम खुद ओह लोग के साथे स्विच कइले बानी।
पफेरा फ्रेमवर्क के सबसे नया संस्करण, 1999। पफेरापायएसिंक के बा , स्टारलेट पर आधारित बा। हालांकि फ्लास्क के एगो एएसजीआई संस्करण बा जवना के नाम बा क्वार्ट, क्वार्ट अवुरी स्टारलेट के बीच के प्रदर्शन के अंतर हमरा खाती काफी रहे कि हम अपना कोड के एकरा बदला स्टारलेट प रिबेस क सकी।
एसिक्रोनस प्रोग्रामिंग बहुत लोग खातिर डेरावे वाला हो सकेला, लेकिन असल में ई कवनो कठिन अवधारणा नइखे जवना के बदौलत Node.js के लोग एक दशक से अधिका पहिले एह अवधारणा के लोकप्रिय बनावत रहे।
हमनी के मल्टीथ्रेडिंग, मल्टीप्रोसेसिंग, डिस्ट्रीब्यूटेड कंप्यूटिंग, प्रोमिस चेनिंग, आ ओह सब मजेदार समय के साथे समवर्तीता से लड़त रहनी जा जवन समय से पहिले कई गो दिग्गज प्रोग्रामर के उमिर बढ़ा दिहलस आ सूखा दिहलस। अब, हम त बस टाइप कर देनी async
हमनी के समारोह के सामने आ... await
कवनो कोड के सामने जवना के निष्पादित करे में कुछ समय लाग सकेला. ई वाकई में नियमित कोड से ढेर वर्बोज बा, बाकी एकर इस्तेमाल करे में बहुत कम परेशानी होला, जबकि सिंक्रनाइजेशन प्रिमिटिव, मैसेज पासिंग, आ वादा के समाधान से निपटे के पड़े ला।
हमनी के स्टारलेट फाइल अईसन लउकेला:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Session benchmark test
import json
import uuid
import psycopg
from starlette.applications import Starlette
from starlette.responses import Response, PlainTextResponse, JSONResponse, RedirectResponse, HTMLResponse
from starlette.routing import Route, Mount, WebSocketRoute
from starlette_session import SessionMiddleware
dbconn = 0
# =====================================================================
async def index(R):
global dbconn
if not dbconn:
dbconn = await psycopg.AsyncConnection.connect('dbname=sessiontest user=sessiontest password=sessiontest')
cursor = await dbconn.execute('''
CREATE TABLE IF NOT EXISTS usersessions(
uid TEXT PRIMARY KEY,
data TEXT
)
''')
await cursor.close()
await dbconn.commit()
sessionid = R.session.get('sessionid', 0)
if not sessionid:
sessionid = uuid.uuid4().hex
R.session['sessionid'] = sessionid
cursor = await dbconn.execute("SELECT data FROM usersessions WHERE uid = %s", [sessionid])
row = await cursor.fetchone()
count = json.loads(row[0])['count'] if row else 0
count += 1
newdata = json.dumps({'count': count})
if count == 1:
await cursor.execute("""
INSERT INTO usersessions(uid, data)
VALUES(%s, %s)
""",
[sessionid, newdata]
)
else:
await cursor.execute("""
UPDATE usersessions
SET data = %s
WHERE uid = %s
""",
[newdata, sessionid]
)
await cursor.close()
await dbconn.commit()
return PlainTextResponse(f'Count is {count}')
# *********************************************************************
app = Starlette(
debug = True,
routes = [
Route('/{path:path}', index, methods = ['GET', 'POST']),
],
)
app.add_middleware(
SessionMiddleware,
secret_key = 'testsecretkey',
cookie_name = "pafera",
)
जईसे की रउवा सभे देख सकत बानी कि एकरा के बहुत हद तक हमनी के फ्लास्क स्क्रिप्ट से कॉपी आ पेस्ट कईल गईल बा जवना में मात्र एक दू गो रूटिंग बदलाव कईल गईल बा अउरी... async/await
कीवर्ड के बा।
कॉपी पेस्ट कोड हमनी के सचमुच केतना सुधार दे सकता?
Python/Starlette
╰─➤ gunicorn --access-logfile - -k uvicorn.workers.UvicornWorker -w 4 starlettesite:app 130 ↵
[2023-03-21 15:42:34 +0800] [2856220] [INFO] Starting gunicorn 20.1.0
╰─➤ wrk -d 10s -t 4 -c 100 http://127.0.0.1:8000
Running 10s test @ http://127.0.0.1:8000
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 21.85ms 10.45ms 67.29ms 55.18%
Req/Sec 1.15k 170.11 1.52k 66.00%
45809 requests in 10.04s, 13.85MB read
Requests/sec: 4562.82
Transfer/sec: 1.38MB
हमनी के एगो नया चैंपियन बा, लेडीज एंड जेंटलमैन! हमनी के पहिले के उच्चतम स्तर हमनी के शुद्ध पीएचपी संस्करण रहे जवन 704 अनुरोध प्रति सेकंड रहे, जवना के बाद हमनी के फ्लास्क संस्करण 1080 अनुरोध प्रति सेकंड से आगे निकल गईल। हमनी के स्टारलेट स्क्रिप्ट 4562 अनुरोध प्रति सेकंड के दर से पिछला सभ दावेदार के कुचल देले बा, मतलब कि शुद्ध पीएचपी के मुक़ाबले 6x सुधार अवुरी फ्लास्क के मुक़ाबले 4x सुधार।
अगर रउआँ अभी तक आपन WSGI पायथन कोड के ASGI में नइखीं बदलले, त अब शुरू करे के बढ़िया समय हो सकेला।
अब तक हमनी के खाली पीएचपी आ पायथन फ्रेमवर्क के कवर कइले बानी जा। हालाँकि, दुनिया के एगो बड़हन हिस्सा वास्तव में अपना वेबसाइट खातिर जावा, डॉटनेट, नोड डॉट जेएस, रूबी ऑन रेल, आ अइसने अउरी टेक्नोलॉजी सभ के इस्तेमाल करे ला। ई कवनो तरीका से दुनिया के सभ इकोसिस्टम आ बायोम के व्यापक अवलोकन ना हवे, एह से कार्बनिक रसायन बिज्ञान के प्रोग्रामिंग समकक्ष काम करे से बचे खातिर हमनी के खाली अइसन ढाँचा चुनब जा जिनहन खातिर कोड टाइप कइल सभसे आसान होखे.. जवना में से जावा निश्चित रूप से नइखे.
जबले कि रउरा के एंड आर सी भा क्नुथ के अपना कॉपी के नीचे लुकाइल ना होखीं कंप्यूटर प्रोग्रामिंग के कला के बारे में बतावल गइल बा पिछला पन्द्रह साल से रउरा शायद Node.js के बारे में सुनले होखब. हमनी में से जे जावास्क्रिप्ट के शुरुआत से बा, ऊ लोग आधुनिक जावास्क्रिप्ट के हालत से या त अविश्वसनीय रूप से डेरा गइल बा, अचरज में बा, भा दुनु, बाकिर एह बात से कवनो इनकार नइखे कि जावास्क्रिप्ट सर्वर पर भी एगो ताकत बन गइल बा जवना के हिसाब लगावल जा सकेला ब्राउजर के रूप में बा। आखिर हमनी के त अब भाषा में नेटिव 64 बिट इंटीजर तक बा! ऊ त अबहीं ले 64 बिट फ्लोट में संग्रहीत कइल हर चीज से कहीं बेहतर बा!
एक्सप्रेसजेएस शायद इस्तेमाल करे में सबसे आसान Node.js सर्वर बा, एहसे हमनी के अपना काउंटर के सेवा देवे खातिर एगो त्वरित आ गंदा Node.js/ExpressJS ऐप करब जा।
/**********************************************************************
* Simple session test using ExpressJS.
**********************************************************************/
var L = console.log;
var uuid = require('uuid4');
var express = require('express');
var session = require('express-session');
var MemoryStore = require('memorystore')(session);
var { Client } = require('pg')
var db = 0;
var app = express();
const PORT = 8000;
//session middleware
app.use(
session({
secret: "secretkey",
saveUninitialized: true,
resave: false,
store: new MemoryStore({
checkPeriod: 1000 * 60 * 60 * 24 // prune expired entries every 24h
})
})
);
app.get('/',
async function(req,res)
{
if (!db)
{
db = new Client({
user: 'sessiontest',
host: '127.0.0.1',
database: 'sessiontest',
password: 'sessiontest'
});
await db.connect();
await db.query(`
CREATE TABLE IF NOT EXISTS usersessions(
uid TEXT PRIMARY KEY,
data TEXT
)`,
[]
);
};
var session = req.session;
if (!session.sessionid)
{
session.sessionid = uuid();
}
var row = 0;
let queryresult = await db.query(`
SELECT data::TEXT
FROM usersessions
WHERE uid = $1`,
[session.sessionid]
);
if (queryresult && queryresult.rows.length)
{
row = queryresult.rows[0].data;
}
var count = 0;
if (row)
{
var data = JSON.parse(row);
data.count += 1;
count = data.count;
await db.query(`
UPDATE usersessions
SET data = $1
WHERE uid = $2
`,
[JSON.stringify(data), session.sessionid]
);
} else
{
await db.query(`
INSERT INTO usersessions(uid, data)
VALUES($1, $2)`,
[session.sessionid, JSON.stringify({count: 1})]
);
count = 1;
}
res.send(`Count is ${count}`);
}
);
app.listen(PORT, () => console.log(`Server Running at port ${PORT}`));
ई कोड असल में पायथन संस्करण सभ के तुलना में लिखल आसान रहल, हालाँकि, नेटिव जावास्क्रिप्ट जब एप्लीकेशन सभ बड़ हो जालें तब काफी बेढंगा हो जाला आ एकरा के ठीक करे के सगरी कोसिस जइसे कि टाइपस्क्रिप्ट जल्दी से पायथन से ढेर वर्बोज हो जाला।
देखल जाव कि ई कइसे काम करेला!
Node.js/ExpressJS
╰─➤ node --version v19.6.0
╰─➤ NODE_ENV=production node nodejsapp.js 130 ↵
Server Running at port 8000
╰─➤ wrk -d 10s -t 4 -c 100 http://127.0.0.1:8000
Running 10s test @ http://127.0.0.1:8000
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 90.41ms 7.20ms 188.29ms 85.16%
Req/Sec 277.15 37.21 393.00 81.66%
11018 requests in 10.02s, 3.82MB read
Requests/sec: 1100.12
Transfer/sec: 390.68KB
रउआँ सभे Node.js' गति, आ ऊ कहानी अधिकतर साँच बाड़ी सँ जवना के बदौलत ओह शानदार काम बा जवन गूगल वी8 जावास्क्रिप्ट इंजन से कइले बा. हालांकि एह मामला में, हालांकि हमनी के क्विक ऐप फ्लास्क स्क्रिप्ट से बेहतर प्रदर्शन करेला, लेकिन एकर एकल थ्रेडेड प्रकृति स्टारलेट नाइट के चार गो एसिंक प्रक्रिया से हरा जाला जवन कि "नी!" कहता।
आईं कुछ अउरी मदद मिल जाव!
╰─➤ pm2 start nodejsapp.js -i 4
[PM2] Spawning PM2 daemon with pm2_home=/home/jim/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/jim/projects/paferarust/nodejsapp.js in cluster_mode (4 instances)
[PM2] Done.
┌────┬──────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼──────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ nodejsapp │ default │ N/A │ cluster │ 37141 │ 0s │ 0 │ online │ 0% │ 64.6mb │ jim │ disabled │
│ 1 │ nodejsapp │ default │ N/A │ cluster │ 37148 │ 0s │ 0 │ online │ 0% │ 64.5mb │ jim │ disabled │
│ 2 │ nodejsapp │ default │ N/A │ cluster │ 37159 │ 0s │ 0 │ online │ 0% │ 56.0mb │ jim │ disabled │
│ 3 │ nodejsapp │ default │ N/A │ cluster │ 37171 │ 0s │ 0 │ online │ 0% │ 45.3mb │ jim │ disabled │
└────┴──────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
ठीक बा! अब चार पर सम चार के लड़ाई हो गइल बा! आईं बेंचमार्क कइल जाव!
╰─➤ wrk -d 10s -t 4 -c 100 http://127.0.0.1:8000
Running 10s test @ http://127.0.0.1:8000
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 45.09ms 19.89ms 176.14ms 60.22%
Req/Sec 558.93 97.50 770.00 66.17%
22234 requests in 10.02s, 7.71MB read
Requests/sec: 2218.69
Transfer/sec: 787.89KB
अभी भी स्टारलेट के स्तर पर बिल्कुल नइखे, लेकिन पांच मिनट के जल्दी जावास्क्रिप्ट हैक खातिर ई खराब नइखे। हमरा खुद के परीक्षण से ई स्क्रिप्ट असल में डेटाबेस इंटरफेसिंग लेवल पर तनी रोकल जा रहल बा काहे कि नोड-पोस्टग्रेस ओतना कुशल कतहीं नइखे जतना पायथन खातिर साइकोपीजी बा. डेटाबेस ड्राइवर के रूप में sqlite पर स्विच कइला से एकही एक्सप्रेसजेएस कोड खातिर प्रति सेकंड 3000 से ढेर अनुरोध मिले ला।
मुख्य बात ई बा कि पायथन के धीमा निष्पादन गति के बावजूद, ASGI फ्रेमवर्क सभ वास्तव में कुछ खास वर्कलोड सभ खातिर Node.js समाधान सभ के साथ प्रतिस्पर्धी हो सके लें।
त अब, हमनी के पहाड़ के चोटी के नजदीक आ रहल बानी जा, आ पहाड़ से हमार मतलब बा कि चूहा आ आदमी दुनु के रिकार्ड कइल सबले अधिका बेंचमार्क स्कोर.
अगर रउआ वेब पर उपलब्ध अधिकतर फ्रेमवर्क बेंचमार्क के देखब त रउआ देखब कि दू गो भाषा बाड़ी स जवन शीर्ष पर हावी होखे के प्रवृत्ति बाड़ी स: C++ आ Rust. हम 90 के दशक से C++ के साथ काम करत बानी, आ इहाँ तक कि MFC/ATL के चीज होखे से पहिले हमार आपन Win32 C++ फ्रेमवर्क भी रहे, एहसे हमरा भाषा के बहुत अनुभव बा। जब रउरा पहिले से जानत होखीं त कवनो चीज का साथे काम कइल बहुते मजेदार ना होखे एहसे हमनी का एकरा बदले रस्ट संस्करण करे जा रहल बानी जा. ;)
जहाँ तक प्रोग्रामिंग भाषा के बात बा त रस्ट अपेक्षाकृत नया बा, लेकिन हमरा खातिर ई एगो कौतुहल के विषय बन गईल जब लिनस टॉरवाल्ड्स घोषणा कईले कि उ रस्ट के लिनक्स कर्नेल प्रोग्रामिंग भाषा के रूप में स्वीकार करीहे। हमनी के पुरान प्रोग्रामर लोग खातिर ई बात लगभग एके जइसन बा कि ई कहल कि ई नया फंगल न्यू एज हिप्पी थिंगी अमेरिकी संविधान में नया संशोधन होखे वाला बा.
अब जब रउरा अनुभवी प्रोग्रामर होखीं त रउरा बैंडवागन पर ओतना तेजी से ना कूदे के आदत होला जतना छोट लोग करेला, ना त भाषा भा लाइब्रेरी में तेजी से बदलाव से रउरा जरि जाइब. (जे केहू एंगुलरजेएस के पहिला संस्करण के इस्तेमाल कइले बा ओकरा मालूम होई कि हम का बात करत बानी.) जंग अबहीं कुछ हद तक ओह प्रयोगात्मक विकास के चरण में बा, आ हमरा ई मजेदार लागत बा कि वेब पर एतना कोड उदाहरण भी नइखे पैकेज के वर्तमान संस्करण के साथ अब संकलित करीं।
हालाँकि, रस्ट एप्लीकेशन सभ द्वारा देखावल गइल परफार्मेंस के इनकार ना कइल जा सके ला। अगर रउरा कबो कोशिश नइखीं कइले रिपग्रेप के बा अऊर fd-खोज के बा बड़ स्रोत कोड पेड़ पर बाहर, रउआँ के ओह लोग के एगो स्पिन जरूर देवे के चाहीं। इहाँ तक कि इ अधिकांश लिनक्स वितरण खातिर भी सिर्फ पैकेज मैनेजर से उपलब्ध बा। रउआ रस्ट के साथे परफॉर्मेंस खातिर वर्बोसिटी के आदान-प्रदान कर रहल बानी... क बहुते के खातिर वाक्पटुता के बहुते के प्रदर्शन के बा।
रस्ट खातिर पूरा कोड तनी बड़ बा, एहसे हमनी के बस इहाँ संबंधित हैंडलर प एक नजर डालब जा:
// =====================================================================
pub async fn RunQuery(
db: &web::Data<Pool>,
query: &str,
args: &[&(dyn ToSql + Sync)]
) -> Result<Vec<tokio_postgres::row::Row>, tokio_postgres::Error>
{
let client = db.get().await.unwrap();
let statement = client.prepare_cached(query).await.unwrap();
client.query(&statement, args).await
}
// =====================================================================
pub async fn index(
req: HttpRequest,
session: Session,
db: web::Data<Pool>,
) -> Result<HttpResponse, Error>
{
let mut count = 1;
if let Some(sessionid) = session.get::<String>("sessionid")?
{
let rows = RunQuery(
&db,
"SELECT data
FROM usersessions
WHERE uid = $1",
&[&sessionid]
).await.unwrap();
if rows.is_empty()
{
let jsondata = serde_json::json!({
"count": 1,
}).to_string();
RunQuery(
&db,
"INSERT INTO usersessions(uid, data)
VALUES($1, $2)",
&[&sessionid, &jsondata]
).await
.expect("Insert failed!");
} else
{
let jsonstring:&str = rows[0].get(0);
let countdata: CountData = serde_json::from_str(jsonstring)?;
count = countdata.count;
count += 1;
let jsondata = serde_json::json!({
"count": count,
}).to_string();
RunQuery(
&db,
"UPDATE usersessions
SET data = $1
WHERE uid = $2
",
&[&jsondata, &sessionid]
).await
.expect("Update failed!");
}
} else
{
let sessionid = Uuid::new_v4().to_string();
let jsondata = serde_json::json!({
"count": 1,
}).to_string();
RunQuery(
&db,
"INSERT INTO usersessions(uid, data)
VALUES($1, $2)",
&[&sessionid, &jsondata]
).await
.expect("Insert failed!");
session.insert("sessionid", sessionid)?;
}
Ok(HttpResponse::Ok().body(format!(
"Count is {:?}",
count
)))
}
इ पायथन/नोड.जेएस संस्करण से बहुत जादे जटिल बा...
Rust/Actix
╰─➤ cargo run --release
[2023-03-21T23:37:25Z INFO actix_server::builder] starting 4 workers
Server running at http://127.0.0.1:8888/
╰─➤ wrk -d 10s -t 4 -c 100 http://127.0.0.1:8888
Running 10s test @ http://127.0.0.1:8888
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 9.93ms 3.90ms 77.18ms 94.87%
Req/Sec 2.59k 226.41 2.83k 89.25%
102951 requests in 10.03s, 24.59MB read
Requests/sec: 10267.39
Transfer/sec: 2.45MB
आ एकरा से बहुते अधिका परफॉर्मेंस!
Actix/deadpool_postgres के इस्तेमाल करे वाला हमनी के रस्ट सर्वर हमनी के पिछला चैंपियन स्टारलेट के +125%, एक्सप्रेसजेएस के +362%, आ शुद्ध पीएचपी के +1366% से हाथ से हरा देला। (पाठक खातिर एगो अभ्यास के रूप में हम लारावेल संस्करण के साथे परफॉर्मेंस डेल्टा छोड़ देब।)
हमरा पता चलल बा कि रस्ट भाषा सीखल खुद दोसरा भाषा से अधिका मुश्किल रहल बा काहे कि एहमें 6502 असेंबली से बाहर हमरा देखल कवनो चीज से बहुते अधिका गोटचा बा, बाकिर अगर राउर रस्ट सर्वर 14x के संख्या ले सकेला यूजर्स के राउर पीएचपी सर्वर के रूप में, तब शायद आखिरकार तकनीक स्विचिंग से कुछ फायदा होखे वाला बा. एही से पफेरा फ्रेमवर्क के अगिला संस्करण रस्ट प आधारित होई। सीखन के वक्र स्क्रिप्टिंग भाषा से बहुते अधिका बा बाकिर प्रदर्शन एकरा लायक होखी. अगर रउरा रस्ट सीखे खातिर समय ना लगा सकीं त आपन टेक स्टैक के स्टारलेट भा नोड.जेएस पर आधारित कइल भी कवनो खराब फैसला नइखे.
पिछला बीस साल में हमनी के सस्ता स्टेटिक होस्टिंग साइट से लैम्प स्टैक के साथे साझा होस्टिंग से लेके एडब्ल्यूएस, एजुर, आ अउरी क्लाउड सेवा के वीपीएस किराया पर लेबे तक पहुँच गइल बानी जा। आजकल कई गो कंपनी सभ केकरा के आधार पर डिजाइन के फैसला लेबे से संतुष्ट कइल जाला कि ऊ लोग जेकरा के मिल सके ला कि ऊ उपलब्ध बा भा सभसे सस्ता बा काहें से कि सुविधाजनक क्लाउड सेवा सभ के आगमन के बाद से धीमा सर्वर आ एप्लीकेशन सभ पर अउरी हार्डवेयर फेंकल आसान हो गइल बा। एहसे ओह लोग के दीर्घकालिक तकनीकी कर्ज के कीमत पर बहुते अल्पकालिक लाभ मिलल बा.
70 साल पहिले सोवियत संघ आ अमेरिका के बीच एगो बड़हन अंतरिक्ष दौड़ भइल रहे। शुरुआती दौर के अधिकतर मील के पत्थर सोवियत जीतले रहे| इनहन के लगे स्पूतनिक में पहिला उपग्रह, लाइका में अंतरिक्ष में पहिला कुत्ता, लूना 2 में पहिला चंद्रमा अंतरिक्ष यान, यूरी गागारिन आ वैलेन्टिना तेरेशकोवा में अंतरिक्ष में पहिला आदमी आ औरत, वगैरह वगैरह...
लेकिन उ लोग धीरे-धीरे तकनीकी कर्जा जमा करत रहले।
हालांकि एह में से हर उपलब्धि खातिर सोवियत संघ सबसे पहिले रहे, लेकिन ओह लोग के इंजीनियरिंग प्रक्रिया अउरी लक्ष्य के चलते उ लोग लंबा समय तक व्यवहार्यता के बजाय अल्पकालिक चुनौती प ध्यान देत रहे| हर बेर कूदला पर ऊ लोग जीत गइल बाकिर ऊ लोग अउरी थकत आ धीमा होखत जात रहे जबकि ओह लोग के प्रतिद्वंद्वी लगातार फिनिश लाइन का ओर बढ़त रहले.
एक बेर नील आर्मस्ट्रांग लाइव टेलीविजन पर चाँद पर आपन ऐतिहासिक कदम उठवले त अमेरिकी लोग अगुवाई कइल, आ फेर सोवियत कार्यक्रम के डगमगात ओहिजा रह गइल. ई आजु के ओह कंपनियन से अलग नइखे जवन अगिला बड़हन काम, अगिला बड़हन पेऑफ, भा अगिला बड़का टेक पर ध्यान दिहले बाड़ी सँ जबकि लमहर समय ले उचित आदत आ रणनीति बनावे में नाकाम रहली सँ.
बाजार में सबसे पहिले होखे के मतलब ई ना होला कि ओह बाजार में रउरा दबंग खिलाड़ी बन जाईं. एकरा अलावे समय निकाल के काम सही तरीका से कईल सफलता के गारंटी ना होखेला, लेकिन निश्चित रूप से आपके लंबा समय तक उपलब्धि के संभावना बढ़ जाला। अगर रउरा अपना कंपनी खातिर टेक लीड बानी त अपना काम के बोझ खातिर सही दिशा आ टूल चुनीं. लोकप्रियता के प्रदर्शन आ दक्षता के जगह मत लेबे दीं.
7z फाइल डाउनलोड कइल चाहत बानी जवना में Rust, ExpressJS, Flask, Starlette, आ Pure PHP स्क्रिप्ट होखे?
लेखक के बारे में बतावल गइल बा |
|
![]() |
जिम जब से 90 के दशक में आईबीएम पीएस/2 वापस मिलल रहे तब से प्रोग्रामिंग करत बाड़े। आज ले ऊ एचटीएमएल आ एसक्यूएल हाथ से लिखल पसंद करे लें, आ अपना काम में दक्षता आ सहीता पर फोकस करे लें। |