Verkkoohjainten suorituskyvyn vertailu 10 ohjelmointikielen versioissa

Ryhmä tutkijoita saksalaisista yliopistoista julkaistu tulokset koe, jonka aikana 10 gigabitin Intel Ixgbe (X10xx) -verkkokorttien vakioohjaimesta kehitettiin 5 versiota eri ohjelmointikielillä. Ohjain toimii käyttäjätilassa ja se on toteutettu C-, Rust-, Go-, C#-, Java-, OCaml-, Haskell-, Swift-, JavaScript- ja Python-kielissä. Koodia kirjoitettaessa pääpaino oli parhaan mahdollisen suorituskyvyn saavuttamisessa kunkin kielen ominaispiirteet huomioiden. Kaikki vaihtoehdot ovat toiminnaltaan identtisiä ja koostuvat noin 1000 koodirivistä. Projektien kehitys levitän BSD-lisenssillä.

Ajurin Rust-versio osoittautui suorituskyvyltään hyvin lähellä referenssiajuria C-kielellä. Kuormituksessa, jossa lähetettiin samanaikaisesti 32 paketin lohkoja, Rust-ohjain oli hieman jäljessä, mutta testeissä, joissa oli yli 32 pakettia lohkoa kohden, nopeus ei käytännössä eronnut C-ohjaimesta ja osoitti suorituskykyä 28 miljoonan käsittelyn tasolla. paketteja sekunnissa palvelimella, jossa on Xeon CPU E3-1230 v2 3.3 GHz.

Verkkoohjainten suorituskyvyn vertailu 10 ohjelmointikielen versioissa

Seuraavan suorituskyvyn markkinaraon valloittivat Go- ja C#-kielen ajurit, jotka osoittivat melko läheisiä tuloksia (Go-ohjain voitti testeissä jopa 16 paketin lohkoilla ja alkoi hieman hävitä yli 16 paketin testeissä lohkossa). 256 paketilla lohkoa kohden C#-ohjaimen huipputeho oli noin 28 miljoonaa pakettia sekunnissa ja Go-ajurin noin 25 miljoonaa pakettia sekunnissa.

Seuraavaksi, melko tiiviillä tuloksilla, olivat kuljettajat
Java, OCaml ja Haskell, jotka olivat jo huomattavasti jäljessä aiemmin harkittuista vaihtoehdoista eivätkä pystyneet ylittämään 12 miljoonan paketin sekuntipalkkia. Swift- ja JavaScript-ajurit osoittivat vielä suuremman viiveen, sillä ne pystyivät käsittelemään streameja 5 miljoonan paketin sekunnissa.

Huippusijoituksen täydensi Python-ajuri, joka pystyi käsittelemään vain 0.14 miljoonaa pakettia sekunnissa. Python-toteutusta käytettiin tulkkien nopeuden arvioimiseen ilman JIT:tä ja ilman erityisiä optimointeja (koodi suoritettiin CPython 3.7:llä eikä se ollut yhteensopiva PyPyn kanssa, mutta on huomattava, että tietojen tallennusrakenteiden optimointi voisi parantaa suorituskykyä noin 10 kertaa ).

Lisäksi suoritettiin latenssitestejä puskuroinnin tehokkuuden ja roskakeräimen vaikutuksen osoittamiseksi. Testaus mittasi latenssia sen jälkeen, kun kuljettaja oli lähettänyt jokaisen paketin eteenpäin, verrattuna sen lähetysaikaan. Johtajat olivat edelleen C- ja Rust-ajurit, joiden tulokset olivat käytännössä erottamattomat 1 miljoonan paketin sekunnissa (noin 20 µs) virtaukselle. Go-kuljettaja suoriutui hyvin jääden vain hieman johtajista ja pysyen myös 20 µs:n tasolla. C#-ohjain osoitti noin 50 µs viiveitä.
Pisin viive oli JavaScript- ja Java-ajureilla (latenssit yli 300 µs).

Verkkoohjainten suorituskyvyn vertailu 10 ohjelmointikielen versioissa

Tutkimuksessa arvioitiin mahdollisuutta kehittää ohjaimia ja käyttöjärjestelmäkomponentteja korkeammalla tasolla kuin C. Tällä hetkellä 39 40:stä Linuxin muistiongelmista liittyy ohjaimiin, joten turvallisemman kielen käyttöön ja ohjainten siirtämiseen pois ytimestä käyttäjätilaan. pysyvät ajan tasalla ja valmistajat kokeilevat jo aktiivisesti tähän suuntaan (esim. Google on kehittänyt TCP-pinon käyttöjärjestelmälle Fuksia Go-kielellä, CloudFlare-yritys luotu QUIC-protokollan käyttöönotto Rustissa, Apple on siirtänyt mobiililaitteiden TCP-pinon käyttäjätilaan).

Työn aikana todettiin, että Rust-kieli on paras ehdokas kuljettajan kehittämiseen. Rustin ominaisuudet poistavat matalan tason muistin hallintaan liittyvät ongelmat noin 2–10 prosentin suorituskyvyn heikkenemisen hinnalla verrattuna C-ajureihin. Go ja C# katsotaan myös sopiviksi järjestelmäkomponenttien luomiseen tilanteissa, joissa roskien keräämisen aiheuttama submillisekunnin latenssi on hyväksyttävää.

Lähde: opennet.ru

Lisää kommentti