Verdigris: Qt uten moc.

Verdigris er et header-bare bibliotek som kan brukes med Qt. Den bruker makroer til a lage et QMetaObject som er bin rt kompatibelt med Qts eget QMetaObject uten a kreve moc. Med andre ord kan du bruke Verdigris-makroer i Qt eller QML-applikasjonen i stedet for noen av Qt-makroene, og du trenger ikke a kjore moc.

Introduksjon.

CopperSpice er en gaffel av Qt 4. Den viktigste raison d’ГЄtre er a bli kvitt moc fordi de anser det darlig nok (IMHO feilaktig). For a gjore det, erstattet de den brukervennlige Qt-makroen med noen mindre vennlige makroer.

CopperSpice er imidlertid en hel gaffel av Qt, noe som betyr at de opprettholder hele biblioteket. Dette betyr ogsa at de gjenskaper et okosystem fra grunnen av. Hvis de hadde gjort det bin rkompatibel, kunne de ha fjernet moc uten a behove hele Qt-biblioteket. Dette er hva Verdigris er.

Et annet problem med CopperSpice sammenlignet med Qt er at det genererer og registrerer QMetaObject pa kjoretid nar du laster applikasjonen. I mellomtiden bruker Verdigris constexpr til a generere QMetaObject ved kompileringstid. Av denne grunn er bin rfiler som bruker CopperSpice mye storre enn bin rfiler ved hjelp av Qt (Moc eller Vedrigris), og tar ogsa mer tid a laste pa grunn av den enorme mengden flyttinger.

Tidligere arbeid.

Det meste av grunnarbeidet er basert pa koden jeg skrev allerede i mitt forrige blogginnlegg: Kan Qt’s moc bli erstattet av C ++ refleksjon ?. I det blogginnlegget provde jeg a se om refleksjon kunne hjelpe til med a erstatte moc, samtidig som det var enklere a bruke de nav rende Qt-makroene. Malet var a pavirke kildekompatibiliteten sa lite som mulig.

CopperSpice bestemte seg for a bruke forskjellige makroer som er mindre praktiske. Makroene til Verdigris er basert eller forbedret pa CopperSpice-ene.

Forskjeller mellom CopperSpice og Verdigris.

(Av kompilatoren)

В В void mySlot (int x);

В В void mySignal (int x);

В WR WRITE setProp.

В В READ getProp.

В В NOTIFY propChanged)

В WR WRITE setProp.

В В READ getProp.

В В NOTIFY propChanged)

В В myPrivateSlot (int x);

W_SLOT (myPrivateSlot, (int), W_Access :: Privat)

Den forste forskjellen i Verdigris er W_OBJECT_IMPL makroen som ma skrives i .cpp-filen. Dette er en av de fa punktene Verdigris er mindre praktisk enn CopperSpice, da de ikke trenger denne makroen.

I CopperSpice kan du ikke definere et spor inline i klassen definisjonen. Du har ikke denne begrensningen med Verdigris. (Oppdatering: Jeg ble fortalt at det er mulig med CopperSpice ved a sette kroppen i CS_SLOT_1-makroen)

Bade CopperSpice og Verdigirs kan ha templated QObject-klasse eller nestet QObject. Verdigris kan imidlertid ikke fungere lokale QObjects (pa grunn av statisk statisk staticMetaObject) og lokale klasser kan ikke ha statiske medlemmer.

Fra et implementeringssynspunkt bruker CopperSpice-makroer __LINE__ til a bygge en unik identifikator, som betyr at to makroer ikke kan settes pa samme linjer. Sa du kan ikke deklarere flere spor i en linje eller deklarere egenskaper eller signaler / spor fra en makro. (som ironisk nok er et av «problemene» de reiste om Qt4s moc). Verdigris makroer har ikke dette problemet.

Den beste maten a l re om hvordan du bruker Verdigris, er a lese gjennom oppl ringen (praktisk hentet til deg gjennom var kodebrowser).

Benchmarks.

Alle referanser ble gjort med CopperSpice 1.2.2, Qt 5.6.0 eller Qt 4.8.3, GCC 6.1.

Kjokkenvask.

Jeg laget KitchenSink-eksemplet fra CopperSpice sammen med CopperSpice, Qt 5 med moc eller med Verdigris (patch). Denne tabellen viser mengden i minutter: sekunder tatt av make -j1.

Jeg var overrasket over a se at Verdigris kompilerer raskere enn a bruke moc. Kostnaden ved a kompilere den genererte koden i en egen kompileringsenhet er det som gjor det langsommere, og inkludert den genererte filen er en vanlig mate a oke samlingen pa (det var ikke gjort i dette tilfellet). CopperSpice er sannsynligvis sa sakte fordi hver oversettelsesenhet trenger a generere koden som genererer meta-objektet for alle medfolgende objekter (inkludert topptekstene fra CsCore, CsGui,.). Verdigris beveger imidlertid det meste av sakte kompileringskoden i en W_OBJECT_IMPL-makro i .cpp-koden som bare analyseres for den tilsvarende oversettelsesenheten. Likevel tar tester sv rt lang tid a kompilere, det er fordi de har mange objekter med mange spesielle metoder / egenskaper og vi sannsynligvis treffer ikke-line re algoritmer i kompilatoren.

Bibliotekets lastetid.

Ethvert program som kobler til et C ++-bibliotek har noe overhead pa grunn av flyttingene og init-delen. Dette referansen knytter bare et nesten tomt program sammen med bibliotekene, og beregner tiden det tar a kjore.

(Qt5Core, Qt5Gui, Qt5Widgets)

Laster CopperSpice er mye langsommere fordi alle MetaObjects ma opprettes og den enorme mengden flyttinger.

Merk: Siden programmet er tomt og ikke har noen QObject pa egen hand, ble det ikke brukt moc eller Verdigris. Qt5 og Qt4 selv ble samlet sammen med moc som vanlig.

Signaler / Slots run-time ytelse.

Jeg bygget Qt-referansene for a teste tilkobling og utgivelse av Qt-signaler. Det er ingen forskjell mellom Verdigris eller normal Qt. Som forventet siden QMetaObject-strukturen er den samme, og den moc-genererte koden tilsvarer den templerte koden.

CopperSpice er raskere for signalutslipp fordi de inneholdt alt, inkludert QMetaObject :: aktivert. Noe vi ikke gjor i Qt fordi vi onsker a opprettholde bin r kompatibilitet og innebygge alt betyr at vi ikke kan endre mye av datastrukturene som brukes til neste store versjon av Qt. Dette bidrar i stor grad til kodestorrelsen som er to storrelsesorden mer enn a bruke Qt.

Implementeringsdetaljer.

Som sagt tidligere var det meste av konstexpr-koden basert pa hva jeg skrev for den forrige forskningen. Jeg matte erstatte std :: tuple med en annen datastruktur fordi std :: tuple viste seg a v re altfor sakte a kompilere. GNUs libstdc + + implementering av std :: tuple gjor kun 16 template rekursjon per parameter bare for a beregne noexpect-klausulen av kopikonstruktoren. Det er ganske begrenset nar standardgrensen for malrekursjon er 256 (sa det betyr maksimalt 16 typer i en tuple). Det er ogsa det faktum at kompilatoren ser ut til a ha drift av kvadratisk kompleksitet avhengig av mengden av malparameter eller instantiering. Jeg har derfor laget min egen bin re trestruktur som kan kompilere i en rimelig tid. I stedet for a ha tuple


Vil du spille i det mest ærlige kasinoet? Vi forbereder det for deg. Prøv her nå!