Qt i Implicit Sharing

Odpowiedz Nowy wątek
2014-12-20 16:42
0

Jakiś czas temu doczytałem, iż wiele klas Qt jest implicit sharing .. mniej więcej rozumiem to 'zjawisko' (w skórcie: nie jest przekazywana kopia (przez wartość) ale sam wskaźnik; i zwiększany jest tzw. refcount), ale chciałbym się odnieść do konkretnych przypadków użycia..

Mam powiedzmy taki kod: (nie ma on za bardzo sensu 'logicznego', ale nie musi mieć .. :) )

 QList<QVariant> function(QStringList list)
{
    QList<QVariant> l;
    ...
    if(list.at(2) == l.at(2))
        return l;
}

Z wiedzy, którą na ten moment posiadam (klasy QStringList i QList są implicit sharing ) to zarówno na zmiennej list jak i zwracanej l operacje będą wykonywane poprzez wskaźnik, tak ? (czyli będzie zachowana swoista oszczędność pamięci ?)

A czy zapis w/w kodu z operatorami referencji & coś zmienia:

 QList<QVariant>& function(const QStringList& list)
{
    QList<QVariant> l;
    ...
    if(list.at(2) == l.at(2))
        return l;
}

? (bo w przypadku 'czystego' C++ ten drugi zapis jest bardziej odpowiedni..)

Pozostało 580 znaków

2015-01-02 15:18
0

Up
// bardzo niechętnie podbiję wątek, ale nadal jestem ciekaw zdania forumowiczów znających temat.. (a w międzyczasie były Święta i wielu osób mogło nie być i nie widzieć wątku ;)

edytowany 1x, ostatnio: adamError, 2015-01-02 15:18

Pozostało 580 znaków

2015-01-02 16:40
2

Pomijając fakt poważnego błędu w drugiej wersji (zwracana referencja do obiektu lokalnego - automatycznego):
Zmiana polega na tym, że w drugim przypadku refcount nie jest zmieniany. Taki kod powinien być szybszy (jest jakiś koszt wykonania płytkiej kopii).
Poza tym, druga wersja całkowicie blokuje możliwość wykonania pełnej kopii (kompilator tego dopilnuje).
W pierwszej wersji jeśli ktoś np użyje operatora [], to spowoduje nieintencjonalne i automatyczne wykonanie pełnej kopii.

przekazywanie dużych obiektów przez wartość jest ogólnie złą praktyką, nawet jeśli stosują one Copy on Write i Implicit Sharing.
Nawet w źródłach Qt nie znajdziesz czegoś takiego (no może pojedyncze przypadki).


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22, 2015-01-02 16:43

Pozostało 580 znaków

2015-01-02 16:47
0

Dodam jeszcze że return musi być w każdym przypadku.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2015-01-03 20:41
0

@MarekR22 - dzięki za odpowiedź. Odnośnie złej praktyki przekazywania dużych obiektów przez wartość.. to słyszałem o tym..

Chciałbym jednak wtedy zapytać jak poprawnie miałaby wyglądać 'ogólna postać' metody, odpowiedzialna za wykonywanie i zwracanie wyników pobranych z bazy danych?

Na ten moment mam przygotowaną następującą metodę:

 
QList<QVariantList> DBClass::SelectByProcedure(QString const& querytext, QList<QVariant> const& arg)
{
    QSqlQuery query;
    query.prepare(querytext);
 
    for (int i=0; i<arg.count();i++)
        query.bindValue(i,arg.at(i));
 
    if (!query.exec()) {
        qDebug() << query.lastError().text();
    }
 
    QList<QVariantList> tab;
 
    if (query.size() > 0 )
    {
        while (query.next())
        {
           QList<QVariant> record;
           for(int i=0; i< query.record().count(); ++i)
              record.append(query.value(i));
 
           tab.append(record);
        }
    }
    else
    {
        qDebug() << "query error";
    }
 
    return tab;
}

Jak powinna wyglądać jej poprawna postać? (chodzi mi przede wszystkim o kwestie związanie z zarządzaniem pamięcią..)

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0