అవును, వర్జీనియా, అక్కడ *ఉంది* a శాంతా క్లాజ్ 2023లో వెబ్ ఫ్రేమ్‌వర్క్‌ల మధ్య వ్యత్యాసం

మార్కెట్ ఒత్తిడి మరియు సాంకేతిక రుణాలకు లొంగిపోయే ముందు వేగంగా పని చేసే వెబ్ సర్వర్ కోడ్‌ను కనుగొనడానికి ఒక ధిక్కరించే ప్రోగ్రామర్'
2023-03-24 11:52:06
👁️ 783
💬 0

కంటెంట్‌లు

  1. పరిచయం
  2. పరీక్ష
  3. PHP/లారావెల్
  4. స్వచ్ఛమైన PHP
  5. లారావెల్‌ని మళ్లీ సందర్శించడం
  6. జంగో
  7. ఫ్లాస్క్
  8. స్టార్లెట్
  9. Node.js/ExpressJS
  10. రస్ట్/యాక్టిక్స్
  11. సాంకేతిక రుణం
  12. వనరులు

పరిచయం

నా ఇటీవలి ఉద్యోగ ఇంటర్వ్యూలలో ఒకదాని తర్వాత, నేను దరఖాస్తు చేసిన కంపెనీ ఇప్పటికీ లారావెల్‌ను ఉపయోగిస్తోందని గ్రహించి నేను ఒక దశాబ్దం క్రితం ప్రయత్నించిన PHP ఫ్రేమ్‌వర్క్‌ను ఉపయోగిస్తున్నానని నేను ఆశ్చర్యపోయాను. ఇది ఆ సమయానికి తగినది, కానీ సాంకేతికత మరియు ఫ్యాషన్‌లో ఒకేలా స్థిరంగా ఉంటే, అది నిరంతరం మార్పు మరియు శైలులు మరియు భావనలను పునరుద్ధరిస్తుంది. మీరు జావాస్క్రిప్ట్ ప్రోగ్రామర్ అయితే, ఈ పాత జోక్ మీకు బాగా తెలిసి ఉండవచ్చు

ప్రోగ్రామర్ 1: "ఈ కొత్త జావాస్క్రిప్ట్ ఫ్రేమ్‌వర్క్ నాకు నచ్చలేదు!"

ప్రోగ్రామర్ 2: "చింతించాల్సిన అవసరం లేదు. కేవలం ఆరు నెలలు వేచి ఉండండి మరియు దాని స్థానంలో మరొకటి ఉంటుంది!"

ఉత్సుకతతో, మేము పాత మరియు కొత్త పరీక్షలను ఉంచినప్పుడు ఏమి జరుగుతుందో చూడాలని నిర్ణయించుకున్నాను. వాస్తవానికి, వెబ్ బెంచ్‌మార్క్‌లు మరియు క్లెయిమ్‌లతో నిండి ఉంది, వీటిలో అత్యంత ప్రజాదరణ పొందినది బహుశా TechEmpower వెబ్ ఫ్రేమ్‌వర్క్ బెంచ్‌మార్క్‌లను ఇక్కడ పొందండి . మేము ఈ రోజు వాటి వలె దాదాపుగా సంక్లిష్టంగా ఏమీ చేయబోము. మేము విషయాలను చక్కగా మరియు సరళంగా ఉంచుతాము, తద్వారా ఈ కథనం మారదు' యుద్ధం మరియు శాంతి , మరియు మీరు చదవడం పూర్తి చేసే సమయానికి మీరు మెలకువగా ఉండటానికి కొంచెం అవకాశం ఉంటుంది. సాధారణ హెచ్చరికలు వర్తిస్తాయి: ఇది మీ మెషీన్‌లో ఒకే విధంగా పని చేయకపోవచ్చు, వివిధ సాఫ్ట్‌వేర్ సంస్కరణలు పనితీరును ప్రభావితం చేయవచ్చు మరియు ష్రోడింగర్ యొక్క పిల్లి నిజానికి ఒక జోంబీ పిల్లిగా మారింది, అతను అదే సమయంలో సగం సజీవంగా మరియు సగం చనిపోయాడు.

పరీక్ష

పర్యావరణాన్ని పరీక్షిస్తోంది

ఈ పరీక్ష కోసం, ఇక్కడ చూపిన విధంగా నేను నా ల్యాప్‌టాప్‌ని చిన్న i5 రన్నింగ్ Manjaro Linuxతో ఉపయోగిస్తాను.

╰─➤  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

చేతిలో పని

ప్రతి అభ్యర్థన కోసం మా కోడ్ మూడు సాధారణ పనులను కలిగి ఉంటుంది:

  1. కుక్కీ నుండి ప్రస్తుత వినియోగదారు సెషన్ IDని చదవండి
  2. డేటాబేస్ నుండి అదనపు సమాచారాన్ని లోడ్ చేయండి
  3. ఆ సమాచారాన్ని వినియోగదారుకు తిరిగి ఇవ్వండి

ఇది ఎలాంటి ఇడియటిక్ పరీక్ష అని మీరు అడగవచ్చు? సరే, మీరు ఈ పేజీకి సంబంధించిన నెట్‌వర్క్ అభ్యర్థనలను పరిశీలిస్తే, మీరు సెషన్‌వర్స్.js అని పిలవబడే ఒకదాన్ని గమనించవచ్చు, అది అదే పని చేస్తుంది.

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

కానీ మేము ఈ పేజీని స్టాటిక్ HTML ఫైల్‌గా క్యాష్ చేసి, వినియోగదారుని విండోలో నుండి 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" అని చెప్పడం ద్వారా వారు పేజీని ఎన్నిసార్లు రిఫ్రెష్ చేసారో వినియోగదారుకు చూపుతుంది. విషయాలను సరళంగా ఉంచడానికి, మేము ప్రస్తుతానికి Redis క్యూలు, Kubernetes భాగాలు లేదా AWS Lambdas నుండి దూరంగా ఉంటాము.

మీరు పేజీని ఎన్నిసార్లు సందర్శించారో చూపుతోంది

ప్రతి వినియోగదారు సెషన్ డేటా PostgreSQL డేటాబేస్‌లో సేవ్ చేయబడుతుంది.

వినియోగదారుల సెషన్ల పట్టిక

మరియు ఈ డేటాబేస్ పట్టిక ప్రతి పరీక్షకు ముందు కత్తిరించబడుతుంది.

కత్తిరించిన తర్వాత టేబుల్

పఫెరా నినాదం సరళమైనది అయినప్పటికీ ప్రభావవంతంగా ఉంటుంది... ఏమైనప్పటికీ చీకటి కాలక్రమం వెలుపల...

అసలైన పరీక్ష ఫలితాలు

PHP/లారావెల్

సరే, ఇప్పుడు మనం చివరకు మన చేతులను మురికిగా చేసుకోవడం ప్రారంభించవచ్చు. మేము లారావెల్ కోసం సెటప్‌ను దాటవేస్తాము ఎందుకంటే ఇది కేవలం స్వరకర్త మరియు శిల్పకారుల సమూహం మాత్రమే. ఆదేశాలు.

ముందుగా, మేము .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);

మరియు గణనను ప్రదర్శించడానికి నియంత్రికను సెట్ చేయండి. Laravel, డిఫాల్ట్‌గా, డేటాబేస్‌లో సెషన్‌లను నిల్వ చేస్తుంది. ఇది కూడా అందిస్తుంది 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 ఇన్‌స్టాలేషన్‌లో ఏదైనా తప్పు ఉందా? php-fpmతో ఇంటర్‌ఫేస్ చేస్తున్నప్పుడు Nginx ఏదో విధంగా నెమ్మదిస్తున్నదా?

స్వచ్ఛమైన PHP

ఈ పేజీని స్వచ్ఛమైన PHP కోడ్‌లో మళ్లీ చేద్దాం.

<?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

అయ్యో! అన్నింటికంటే మా PHP ఇన్‌స్టాలేషన్‌లో తప్పు ఏమీ లేనట్లు కనిపిస్తోంది. స్వచ్ఛమైన PHP వెర్షన్ సెకనుకు 700 అభ్యర్థనలను చేస్తోంది.

PHPలో తప్పు ఏమీ లేకుంటే, బహుశా మేము లారావెల్‌ను తప్పుగా కాన్ఫిగర్ చేసామా?

లారావెల్‌ని మళ్లీ సందర్శించడం

కాన్ఫిగరేషన్ సమస్యలు మరియు పనితీరు చిట్కాల కోసం వెబ్‌ను శోధించిన తర్వాత, ప్రతి అభ్యర్థన కోసం వాటిని ప్రాసెస్ చేయకుండా నిరోధించడానికి కాన్ఫిగరేషన్ మరియు రూట్ డేటాను కాష్ చేయడం అత్యంత ప్రజాదరణ పొందిన రెండు సాంకేతికతలు. అందువల్ల, మేము వారి సలహాలను తీసుకుంటాము మరియు ఈ చిట్కాలను ప్రయత్నించండి.

╰─➤  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 వంతు మాత్రమే చేస్తున్నాము.

ఈ పరీక్షలో ఏదో తప్పు జరిగిందని మీరు అనుకుంటే, మీరు Lucinda PHP ఫ్రేమ్‌వర్క్ రచయితతో మాట్లాడాలి. అతని పరీక్ష ఫలితాలలో, అతను కలిగి ఉన్నాడు లూసిండా లారావెల్‌ను ఓడించాడు HTML అభ్యర్థనల కోసం 36x మరియు JSON అభ్యర్థనల కోసం 90x.

Apache మరియు Nginx రెండింటితో నా స్వంత మెషీన్‌లో పరీక్షించిన తర్వాత, నేను అతనిని అనుమానించడానికి ఎటువంటి కారణం లేదు. లారావెల్ నిజంగా న్యాయమైనది అని నెమ్మదిగా! PHP స్వతహాగా అంత చెడ్డది కాదు, కానీ మీరు ప్రతి అభ్యర్థనకు లారావెల్ జోడించే అదనపు ప్రాసెసింగ్‌లన్నింటినీ జోడించిన తర్వాత, 2023లో లారావెల్‌ని ఎంపికగా సిఫార్సు చేయడం నాకు చాలా కష్టంగా ఉంది.

జంగో

PHP/Wordpress ఖాతాలు వెబ్‌లోని అన్ని వెబ్‌సైట్‌లలో దాదాపు 40% , ఇది చాలా ప్రబలమైన ఫ్రేమ్‌వర్క్‌గా మారింది. వ్యక్తిగతంగా అయితే, ఆ అసాధారణమైన రుచినిచ్చే ఆహారం కోసం నాకు అకస్మాత్తుగా అనియంత్రిత కోరిక ఉందని నేను కనుగొన్న దానికంటే ప్రజాదరణ నాణ్యతగా అనువదించాల్సిన అవసరం లేదని నేను గుర్తించాను. ప్రపంచంలో అత్యంత ప్రసిద్ధ రెస్టారెంట్ ... మెక్‌డొనాల్డ్&#x27; మేము ఇప్పటికే స్వచ్ఛమైన PHP కోడ్‌ని పరీక్షించాము కాబట్టి, మేము Wordpressని పరీక్షించడం లేదు, ఎందుకంటే Wordpressకు సంబంధించిన ఏదైనా నిస్సందేహంగా మేము స్వచ్ఛమైన PHPతో గమనించిన సెకనుకు 700 అభ్యర్థనల కంటే తక్కువగా ఉంటుంది.

జంగో అనేది చాలా కాలంగా ఉన్న మరొక ప్రసిద్ధ ఫ్రేమ్‌వర్క్. మీరు దీన్ని గతంలో ఉపయోగించినట్లయితే, మీరు కోరుకున్న విధంగా ప్రతిదాన్ని కాన్ఫిగర్ చేయడం ఎంత బాధించేదో దానితో పాటు దాని అద్భుతమైన డేటాబేస్ అడ్మినిస్ట్రేషన్ ఇంటర్‌ఫేస్‌ను మీరు చాలా ఇష్టంగా గుర్తుంచుకుంటారు. 2023లో జంగో ఎంత బాగా పనిచేస్తుందో చూద్దాం, ప్రత్యేకించి అది వెర్షన్ 4.0కి జోడించిన కొత్త ASGI ఇంటర్‌ఫేస్‌తో.

జాంగోను సెటప్ చేయడం అనేది లారావెల్‌ని సెటప్ చేయడానికి చాలా పోలి ఉంటుంది, ఎందుకంటే అవి రెండూ MVC ఆర్కిటెక్చర్‌లు స్టైలిష్‌గా మరియు సరైనవిగా ఉండే వయస్సు నుండి వచ్చాయి. మేము బోరింగ్ కాన్ఫిగరేషన్‌ను దాటవేసి, వీక్షణను సెటప్ చేయడానికి నేరుగా వెళ్తాము.

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 అభ్యర్థనల వద్ద అస్సలు చెడ్డది కాదు. ఇది స్వచ్ఛమైన PHP వెర్షన్ పనితీరులో సగం మాత్రమే, అయితే ఇది లారావెల్ వెర్షన్‌తో పోలిస్తే 12 రెట్లు ఎక్కువ. జాంగో వర్సెస్ లారావెల్ అస్సలు పోటీ లేదు.

ఫ్లాస్క్

వంటగది-సింక్ ఫ్రేమ్‌వర్క్‌లతో సహా పెద్ద ప్రతిదీ కాకుండా, మిగిలిన వాటిని నిర్వహించడానికి మిమ్మల్ని అనుమతించేటప్పుడు కొన్ని ప్రాథమిక సెటప్‌లను చేసే చిన్న ఫ్రేమ్‌వర్క్‌లు కూడా ఉన్నాయి. ఉపయోగించడానికి ఉత్తమమైన వాటిలో ఒకటి ఫ్లాస్క్ మరియు దాని ASGI కౌంటర్ క్వార్ట్. నా స్వంతం PaferaPy ఫ్రేమ్‌వర్క్ ఫ్లాస్క్ పైన నిర్మించబడింది, కాబట్టి పనితీరును కొనసాగిస్తూనే పనులు చేయడం ఎంత సులభమో నాకు బాగా తెలుసు.

#!/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}'

మీరు చూడగలిగినట్లుగా, ఫ్లాస్క్ స్క్రిప్ట్ స్వచ్ఛమైన PHP స్క్రిప్ట్ కంటే చిన్నది. నేను ఉపయోగించిన అన్ని భాషలలో, టైప్ చేసిన కీస్ట్రోక్‌ల పరంగా బహుశా పైథాన్ అత్యంత వ్యక్తీకరణ భాష అని నేను కనుగొన్నాను. కలుపులు మరియు కుండలీకరణాలు లేకపోవడం, లిస్ట్ మరియు డిక్ట్ కాంప్రహెన్షన్‌లు మరియు సెమికోలన్‌ల కంటే ఇండెంటేషన్ ఆధారంగా నిరోధించడం వంటివి పైథాన్‌ను దాని సామర్థ్యాలలో సరళంగా కాకుండా శక్తివంతమైనవిగా చేస్తాయి.

దురదృష్టవశాత్తూ, పైథాన్‌లో ఎంత సాఫ్ట్‌వేర్ వ్రాయబడినప్పటికీ, అక్కడ నెమ్మదిగా సాధారణ ప్రయోజన భాష కూడా ఉంది. అందుబాటులో ఉన్న పైథాన్ లైబ్రరీల సంఖ్య సారూప్య భాషల కంటే నాలుగు రెట్లు ఎక్కువ మరియు విస్తారమైన డొమైన్‌లను కవర్ చేస్తుంది, అయినప్పటికీ పైథాన్ వేగంగా లేదా 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

మా ఫ్లాస్క్ స్క్రిప్ట్ వాస్తవానికి మా స్వచ్ఛమైన PHP వెర్షన్ కంటే వేగంగా ఉంటుంది!

మీరు దీన్ని చూసి ఆశ్చర్యపోయినట్లయితే, మేము గునికార్న్ సర్వర్‌ను ప్రారంభించినప్పుడు మా ఫ్లాస్క్ యాప్ దాని ప్రారంభీకరణ మరియు కాన్ఫిగరేషన్‌ను పూర్తి చేస్తుందని మీరు గ్రహించాలి, అయితే కొత్త అభ్యర్థన వచ్చిన ప్రతిసారీ PHP స్క్రిప్ట్‌ను మళ్లీ అమలు చేస్తుంది. ఇది&#x27; ;అప్పటికే కారును స్టార్ట్ చేసి రోడ్డు పక్కన వేచి ఉన్న యువకుడు, ఆసక్తిగల టాక్సీ డ్రైవర్‌గా ఫ్లాస్క్‌తో సమానం, అయితే PHP అనేది తన ఇంటి వద్ద కాల్ వస్తుందని వేచి ఉండి, ఆ తర్వాత మాత్రమే డ్రైవ్ చేసే పాత డ్రైవర్. నిన్ను పికప్ చేయడానికి. పాత పాఠశాల కుర్రాడిగా ఉండటం మరియు సాదా HTML మరియు SHTML ఫైల్‌లకు PHP అద్భుతమైన మార్పు చేసిన రోజుల నుండి వస్తున్నందున, ఎంత సమయం గడిచిపోయిందో తెలుసుకోవడం కొంచెం విచారకరం, కానీ డిజైన్ తేడాలు నిజంగా PHPకి కష్టతరం చేస్తాయి. పైథాన్, జావా మరియు Node.js సర్వర్‌లకు వ్యతిరేకంగా పోటీపడండి, ఇవి కేవలం మెమరీలో ఉండి, ఒక గారడీదారుని అతి చురుకైన సౌలభ్యంతో అభ్యర్థనను నిర్వహిస్తాయి.

స్టార్లెట్

ఫ్లాస్క్ ఇప్పటివరకు మా వేగవంతమైన ఫ్రేమ్‌వర్క్ కావచ్చు, కానీ ఇది నిజానికి చాలా పాత సాఫ్ట్‌వేర్. పైథాన్ కమ్యూనిటీ కొన్ని సంవత్సరాల క్రితం కొత్త అసమకాలిక ASGI సర్వర్‌లకు మారిపోయింది మరియు వాస్తవానికి, నేను వారితో పాటు మారాను.

Pafera ఫ్రేమ్‌వర్క్ యొక్క సరికొత్త వెర్షన్, PaferaPyAsync , స్టార్లెట్ ఆధారంగా రూపొందించబడింది. క్వార్ట్ అని పిలువబడే ఫ్లాస్క్ యొక్క ASGI వెర్షన్ ఉన్నప్పటికీ, క్వార్ట్ మరియు స్టార్‌లెట్ మధ్య పనితీరు వ్యత్యాసాలు నాకు బదులుగా స్టార్‌లెట్‌పై నా కోడ్‌ని రీబేస్ చేయడానికి సరిపోతాయి.

అసమకాలిక ప్రోగ్రామింగ్ చాలా మంది వ్యక్తులను భయపెడుతుంది, అయితే ఇది నిజానికి కష్టమైన కాన్సెప్ట్ కాదు, దశాబ్దం క్రితం కాన్సెప్ట్‌ను ప్రాచుర్యంలోకి తెచ్చిన 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 అభ్యర్థనలతో మా స్వచ్ఛమైన PHP వెర్షన్, ఇది సెకనుకు 1080 అభ్యర్థనలతో మా ఫ్లాస్క్ వెర్షన్ ద్వారా అధిగమించబడింది. మా స్టార్‌లెట్ స్క్రిప్ట్ సెకనుకు 4562 అభ్యర్థనల వద్ద మునుపటి పోటీదారులందరినీ క్రష్ చేస్తుంది, అంటే స్వచ్ఛమైన PHP కంటే 6x మెరుగుదల మరియు ఫ్లాస్క్‌పై 4x మెరుగుదల.

మీరు ఇంకా మీ WSGI పైథాన్ కోడ్‌ని ASGIకి మార్చకుంటే, ఇప్పుడు ప్రారంభించడానికి మంచి సమయం కావచ్చు.

Node.js/ExpressJS

ఇప్పటివరకు, మేము PHP మరియు పైథాన్ ఫ్రేమ్‌వర్క్‌లను మాత్రమే కవర్ చేసాము. అయినప్పటికీ, ప్రపంచంలోని అధిక భాగం తమ వెబ్‌సైట్‌ల కోసం Java, DotNet, Node.js, Ruby on Rails మరియు ఇతర సాంకేతికతలను ఉపయోగిస్తున్నారు. ఇది ప్రపంచంలోని అన్ని పర్యావరణ వ్యవస్థలు మరియు బయోమ్‌ల యొక్క సమగ్ర అవలోకనం కాదు, కాబట్టి ఆర్గానిక్ కెమిస్ట్రీకి సమానమైన ప్రోగ్రామింగ్‌ను చేయకుండా ఉండటానికి, మేము కోడ్‌ను టైప్ చేయడానికి సులభమైన ఫ్రేమ్‌వర్క్‌లను మాత్రమే ఎంచుకుంటాము.. ఇందులో జావా ఖచ్చితంగా కాదు.

మీరు మీ K&R C లేదా Knuth&#x27;ల కాపీ కింద దాచి ఉంటే తప్ప కంప్యూటర్ ప్రోగ్రామింగ్ కళ గత పదిహేనేళ్లుగా, మీరు బహుశా Node.js గురించి విన్నారు. జావాస్క్రిప్ట్ ప్రారంభం నుండి మనలో ఉన్నవారు ఆధునిక జావాస్క్రిప్ట్ స్థితిని చూసి చాలా భయపడ్డారు, ఆశ్చర్యపోతారు లేదా ఇద్దరూ ఉన్నారు, అయితే జావాస్క్రిప్ట్ సర్వర్‌లలో కూడా లెక్కించదగిన శక్తిగా మారిందని తిరస్కరించడం లేదు. బ్రౌజర్‌లుగా. అన్నింటికంటే, మనకు ఇప్పుడు భాషలో స్థానిక 64 బిట్ పూర్ణాంకాలు కూడా ఉన్నాయి! ఇప్పటివరకు 64 బిట్ ఫ్లోట్‌లలో నిల్వ చేయబడిన ప్రతిదాని కంటే ఇది చాలా మెరుగైనది!

ExpressJS బహుశా ఉపయోగించడానికి సులభమైన 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&#x27; గురించిన పురాతన (ఇంటర్నెట్ ప్రమాణాల ప్రకారం పురాతనమైనది... వేగం, మరియు ఆ కథనాలు V8 జావాస్క్రిప్ట్ ఇంజిన్‌తో Google చేసిన అద్భుతమైన పనికి ధన్యవాదాలు. అయితే ఈ సందర్భంలో, మా శీఘ్ర అనువర్తనం ఫ్లాస్క్ స్క్రిప్ట్‌ను అధిగమించినప్పటికీ, దాని సింగిల్ థ్రెడ్ స్వభావం &quot;ని!&quot; అని చెప్పే స్టార్లెట్ నైట్ చేత నిర్వహించబడే నాలుగు అసమకాలిక ప్రక్రియల ద్వారా ఓడిపోయింది.

మరికొంత సహాయం పొందుదాం!

╰─➤  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 │
└────┴──────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘

సరే! ఇప్పుడు ఇది నాలుగు యుద్ధంలో సమానమైన నాలుగు! లెట్&#x27;

╰─➤  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

ఇప్పటికీ స్టార్లెట్ స్థాయిలో లేదు, కానీ శీఘ్ర ఐదు నిమిషాల JavaScript హాక్ కోసం ఇది చెడ్డది కాదు. నా స్వంత పరీక్ష నుండి, ఈ స్క్రిప్ట్ వాస్తవానికి డేటాబేస్ ఇంటర్‌ఫేసింగ్ స్థాయిలో కొంత వెనుకబడి ఉంది ఎందుకంటే నోడ్-పోస్ట్‌గ్రెస్ పైథాన్‌కు సైకాప్‌జి ఉన్నంత సమర్థవంతంగా ఎక్కడా లేదు. డేటాబేస్ డ్రైవర్‌గా sqliteకి మారడం ద్వారా అదే ExpressJS కోడ్ కోసం సెకనుకు 3000 కంటే ఎక్కువ అభ్యర్థనలు లభిస్తాయి.

గమనించదగ్గ ప్రధాన విషయం ఏమిటంటే, పైథాన్ యొక్క నెమ్మదిగా అమలు వేగం ఉన్నప్పటికీ, ASGI ఫ్రేమ్‌వర్క్‌లు వాస్తవానికి నిర్దిష్ట పనిభారం కోసం Node.js సొల్యూషన్‌లతో పోటీగా ఉంటాయి.

రస్ట్/యాక్టిక్స్

కాబట్టి ఇప్పుడు, మేము పర్వత శిఖరానికి దగ్గరగా ఉన్నాము మరియు పర్వతం ద్వారా, ఎలుకలు మరియు పురుషులు ఒకే విధంగా నమోదు చేసిన అత్యధిక బెంచ్‌మార్క్ స్కోర్‌లు అని నా ఉద్దేశ్యం.

మీరు వెబ్‌లో అందుబాటులో ఉన్న చాలా ఫ్రేమ్‌వర్క్ బెంచ్‌మార్క్‌లను పరిశీలిస్తే, అగ్రస్థానంలో ఆధిపత్యం చెలాయించే రెండు భాషలు ఉన్నాయని మీరు గమనించవచ్చు: C++ మరియు రస్ట్. నేను 90ల నుండి C++తో పనిచేశాను మరియు MFC/ATL కంటే ముందు నేను నా స్వంత Win32 C++ ఫ్రేమ్‌వర్క్‌ను కూడా కలిగి ఉన్నాను, కాబట్టి నాకు భాషతో చాలా అనుభవం ఉంది. మీకు ఇప్పటికే తెలిసినప్పుడు దానితో పని చేయడం చాలా సరదాగా ఉండదు, కాబట్టి మేము బదులుగా రస్ట్ వెర్షన్‌ని చేయబోతున్నాము. ;)

ప్రోగ్రామింగ్ లాంగ్వేజ్‌లకు వెళ్లేంత వరకు రస్ట్ సాపేక్షంగా కొత్తది, కానీ లైనస్ టోర్వాల్డ్స్ తాను రస్ట్‌ను లైనక్స్ కెర్నల్ ప్రోగ్రామింగ్ లాంగ్వేజ్‌గా అంగీకరిస్తానని ప్రకటించినప్పుడు అది నాకు ఆసక్తిని కలిగించింది. పాత ప్రోగ్రామర్‌ల కోసం, ఈ కొత్త ఫాంగిల్ న్యూ ఏజ్ హిప్పీ థింగ్‌కీ U.S. రాజ్యాంగానికి కొత్త సవరణ కాబోతోందని చెప్పినట్లుగానే ఉంది.

ఇప్పుడు, మీరు అనుభవజ్ఞులైన ప్రోగ్రామర్‌గా ఉన్నప్పుడు, మీరు చిన్నవారు చేసేంత వేగంగా బ్యాండ్‌వాగన్‌పైకి వెళ్లరు, లేదంటే భాష లేదా లైబ్రరీలలో వేగవంతమైన మార్పుల వల్ల మీరు కాలిపోవచ్చు. (AngularJS యొక్క మొదటి వెర్షన్‌ని ఉపయోగించిన ఎవరికైనా నేను ఏమి మాట్లాడుతున్నానో తెలుస్తుంది.) రస్ట్ ఇప్పటికీ ఆ ప్రయోగాత్మక అభివృద్ధి దశలోనే ఉంది మరియు వెబ్‌లో చాలా కోడ్ ఉదాహరణలు కూడా లేకపోవడం నాకు హాస్యాస్పదంగా ఉంది. ప్యాకేజీల యొక్క ప్రస్తుత సంస్కరణలతో ఇకపై కంపైల్ చేయండి.

అయితే, రస్ట్ అప్లికేషన్‌లు చూపిన పనితీరును తిరస్కరించలేము. మీరు ఎప్పుడూ ప్రయత్నించకపోతే రిప్గ్రెప్ లేదా fd-కనుగొను పెద్ద సోర్స్ కోడ్ చెట్లపై, మీరు ఖచ్చితంగా వారికి స్పిన్ ఇవ్వాలి. అవి కేవలం ప్యాకేజీ మేనేజర్ నుండి చాలా Linux పంపిణీలకు కూడా అందుబాటులో ఉన్నాయి. మీరు రస్ట్‌తో పనితీరు కోసం వెర్బోసిటీని మార్పిడి చేస్తున్నారు... a చాలా a కోసం వెర్బోసిటీ చాలా పనితీరు యొక్క.

రస్ట్ కోసం పూర్తి కోడ్ కొంచెం పెద్దది, కాబట్టి మేము ఇక్కడ సంబంధిత హ్యాండ్లర్‌లను పరిశీలిస్తాము:

// =====================================================================
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
  )))
}

ఇది Python/Node.js సంస్కరణల కంటే చాలా క్లిష్టంగా ఉంటుంది...

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%, ExpressJSని +362% మరియు స్వచ్ఛమైన PHPని +1366% ఓడించింది. (నేను పాఠకులకు వ్యాయామంగా లారావెల్ వెర్షన్‌తో పనితీరు డెల్టాను వదిలివేస్తాను.)

6502 అసెంబ్లీ వెలుపల నేను చూసిన వాటి కంటే రస్ట్ లాంగ్వేజ్ నేర్చుకోవడం చాలా కష్టమైనదని నేను కనుగొన్నాను, అయితే మీ రస్ట్ సర్వర్ దాని సంఖ్య కంటే 14 రెట్లు ఎక్కువ పొందగలిగితే మీ PHP సర్వర్‌గా వినియోగదారులు, ఆపై సాంకేతిక పరిజ్ఞానాన్ని మార్చుకోవడం ద్వారా పొందగలిగేది ఏదైనా ఉండవచ్చు. అందుకే Pafera ఫ్రేమ్‌వర్క్ యొక్క తదుపరి వెర్షన్ రస్ట్ ఆధారంగా రూపొందించబడుతుంది. స్క్రిప్టింగ్ లాంగ్వేజ్‌ల కంటే లెర్నింగ్ కర్వ్ చాలా ఎక్కువ, కానీ పనితీరు విలువైనదిగా ఉంటుంది. మీరు రస్ట్ నేర్చుకోవడానికి సమయాన్ని వెచ్చించలేకపోతే, Starlette లేదా Node.jsలో మీ టెక్ స్టాక్‌ను ఆధారం చేసుకోవడం కూడా చెడు నిర్ణయం కాదు.

సాంకేతిక రుణం

గత ఇరవై సంవత్సరాలలో, మేము చౌక స్టాటిక్ హోస్టింగ్ సైట్‌ల నుండి LAMP స్టాక్‌లతో షేర్డ్ హోస్టింగ్‌కు VPSలను AWS, Azure మరియు ఇతర క్లౌడ్ సేవలకు అద్దెకు తీసుకున్నాము. ఈ రోజుల్లో, అనుకూలమైన క్లౌడ్ సేవలు అందుబాటులోకి వచ్చినందున లేదా చౌకైన వాటిని కనుగొనగలిగే వారి ఆధారంగా డిజైన్ నిర్ణయాలు తీసుకోవడంలో చాలా కంపెనీలు సంతృప్తి చెందాయి, ఎందుకంటే అనుకూలమైన క్లౌడ్ సేవలు నెమ్మదిగా ఉన్న సర్వర్‌లు మరియు అప్లికేషన్‌ల వద్ద మరింత హార్డ్‌వేర్‌ను విసిరేయడాన్ని సులభతరం చేశాయి. ఇది దీర్ఘకాలిక సాంకేతిక రుణాల ఖర్చుతో వారికి గొప్ప స్వల్పకాలిక లాభాలను అందించింది.

కాలిఫోర్నియా సర్జన్ జనరల్ హెచ్చరిక: ఇది నిజమైన స్పేస్ డాగ్ కాదు.

70 సంవత్సరాల క్రితం, సోవియట్ యూనియన్ మరియు యునైటెడ్ స్టేట్స్ మధ్య గొప్ప అంతరిక్ష పోటీ జరిగింది. సోవియట్‌లు చాలా ప్రారంభ మైలురాళ్లను గెలుచుకున్నారు. వారు స్పుత్నిక్‌లో మొదటి ఉపగ్రహాన్ని, లైకాలో అంతరిక్షంలోకి వెళ్లిన మొదటి కుక్కను, లూనా 2లో మొదటి చంద్రుని అంతరిక్ష నౌకను, యూరి గగారిన్ మరియు వాలెంటినా తెరేష్‌కోవాలో అంతరిక్షంలోకి వెళ్లిన మొదటి పురుషుడు మరియు స్త్రీని కలిగి ఉన్నారు.

కానీ వారు నెమ్మదిగా సాంకేతిక రుణాన్ని కూడబెట్టుకున్నారు.

సోవియట్‌లు ఈ విజయాల్లో ప్రతిదానికి మొదటి స్థానంలో ఉన్నప్పటికీ, వారి ఇంజనీరింగ్ ప్రక్రియలు మరియు లక్ష్యాలు దీర్ఘకాలిక సాధ్యత కంటే స్వల్పకాలిక సవాళ్లపై దృష్టి పెట్టేలా చేస్తున్నాయి. వారు దూకిన ప్రతిసారీ వారు గెలుపొందారు, కానీ వారి ప్రత్యర్థులు ముగింపు రేఖ వైపు స్థిరమైన పురోగతిని కొనసాగించినప్పుడు వారు మరింత అలసిపోయారు మరియు నెమ్మదిగా ఉన్నారు.

ప్రత్యక్ష టెలివిజన్‌లో నీల్ ఆర్మ్‌స్ట్రాంగ్ చంద్రునిపై తన చారిత్రాత్మక అడుగులు వేసిన తర్వాత, అమెరికన్లు నాయకత్వం వహించారు, ఆపై సోవియట్ కార్యక్రమం విఫలమవడంతో అక్కడే ఉండిపోయారు. సుదీర్ఘకాలం పాటు సరైన అలవాట్లు మరియు వ్యూహాలను అభివృద్ధి చేయడంలో విఫలమవుతున్నప్పుడు, తదుపరి పెద్ద విషయం, తదుపరి పెద్ద చెల్లింపు లేదా తదుపరి పెద్ద సాంకేతికతపై దృష్టి సారించిన కంపెనీల కంటే ఇది భిన్నంగా లేదు.

మార్కెట్‌లో మొదటి వ్యక్తి కావడం అంటే మీరు ఆ మార్కెట్‌లో ఆధిపత్య ప్లేయర్ అవుతారని కాదు. ప్రత్యామ్నాయంగా, పనులను సరిగ్గా చేయడానికి సమయాన్ని వెచ్చించడం విజయానికి హామీ ఇవ్వదు, కానీ దీర్ఘకాలిక విజయాల అవకాశాలను ఖచ్చితంగా పెంచుతుంది. మీరు మీ కంపెనీకి టెక్ లీడ్ అయితే, మీ పనిభారం కోసం సరైన దిశ మరియు సాధనాలను ఎంచుకోండి. పనితీరు మరియు సామర్థ్యాన్ని భర్తీ చేయడానికి ప్రజాదరణను అనుమతించవద్దు.

వనరులు

రస్ట్, ఎక్స్‌ప్రెస్‌జెఎస్, ఫ్లాస్క్, స్టార్‌లెట్ మరియు ప్యూర్ PHP స్క్రిప్ట్‌లను కలిగి ఉన్న 7z ఫైల్‌ను డౌన్‌లోడ్ చేయాలనుకుంటున్నారా?

రచయిత గురించి

జిమ్ 90లలో తిరిగి IBM PS/2ని పొందినప్పటి నుండి ప్రోగ్రామింగ్ చేస్తున్నాడు. ఈ రోజు వరకు, అతను ఇప్పటికీ HTML మరియు SQLలను చేతితో రాయడానికి ఇష్టపడతాడు మరియు అతని పనిలో సమర్థత మరియు ఖచ్చితత్వంపై దృష్టి పెడతాడు.