Инициализация.. какой более эффективен?

Чтобы различать разных типов партнеров, вы можете использовать прокси-моделей .

class PartnerManager(models.Manager):
    def __init__(self, partner_type):
        super().__init__()
        self.partner_type = partner_type

    def get_queryset(self):
        return super().get_queryset().filter(typeid=self.partner_type)

class Client_Partner(Trading_Partner):
    objects = PartnerManager(1)
    class Meta(Trading_Partner.Meta):
        proxy = True

class Parent_Partner(Trading_Partner):
    objects = PartnerManager(0)
    class Meta(Trading_Partner.Meta):
        proxy = True

class Supplier_Partner(Trading_Partner):
    objects = PartnerManager(2)
    class Meta(Trading_Partner.Meta):
        proxy = True

Но я не знаю, возможно ли это с неуправляемыми моделями.

10
задан strager 12 March 2009 в 03:30
поделиться

4 ответа

Скомпилируйте обоих, посмотрите на ассемблер. Первым является тот меньше инструкции...

; 9    :    std::string f("Hello");

    push    OFFSET ??_C@_05COLMCDPH@Hello?$AA@
    lea ecx, DWORD PTR _f$[esp+80]
    call    DWORD PTR __imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z

; 10   :    std::string g = "Hello";

    push    OFFSET ??_C@_05COLMCDPH@Hello?$AA@
    lea ecx, DWORD PTR _g$[esp+80]
    mov DWORD PTR __$EHRec$[esp+88], 0
    call    DWORD PTR __imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z

... но это - артефакт, потому что это было первое, которое видел компилятор. Измените код путем свопинга порядка:

; 9    :    std::string g1 = "Hello";

    push    OFFSET ??_C@_05COLMCDPH@Hello?$AA@
    lea ecx, DWORD PTR _g1$[esp+136]
    call    DWORD PTR __imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z

; 10   :    std::string f1("Hello");

    push    OFFSET ??_C@_05COLMCDPH@Hello?$AA@
    lea ecx, DWORD PTR _f1$[esp+136]
    mov DWORD PTR __$EHRec$[esp+144], 0
    call    DWORD PTR __imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z

... и о чудо, вторым является тот меньше инструкции.

Мы также видим, что этот компилятор (Microsoft VC ++ 2005, настройки Release) генерировал тот же ассемблер для обеих версий. Таким образом, это не имеет никакого значения в этом компиляторе, и можно доказать его.

7
ответ дан 3 December 2019 в 14:54
поделиться

Другие ответы все корректны, но также помните, что это, вероятно, не имеет значения. Это будет редким, очень редким, невероятно редким, та строковая эффективность инициализации будет когда-либо влиять на скорость Вашей программы даже частью секунды.

Самим вопросом является забавный, потому что он помогает показать операции конструкторов C++ и присвоений, но на практике при пребывании в течение времени, пытаясь оптимизировать это (и отправляя на ТАК доказательство достаточно, Вы..) Вы действительно наклоняетесь в ветряных мельницах.

Лучше избежать отвлечения и потратить Ваше усилие в другом месте.

1
ответ дан 3 December 2019 в 14:54
поделиться

Единственная реальная разница - то, что первый технически требует использования конструктора копии, но компилятору позволяют игнорировать его так, чтобы эффективность была идентична в обоих случаях.

Однако первое требует, чтобы конструктор копии был доступным (т.е. не частным), даже если это на самом деле не используется.

2
ответ дан 3 December 2019 в 14:54
поделиться

Я ответил на это здесь

Одна вещь я поместил в этот ответ здесь: Ни один не использует оператора присваивания.

Короткое объяснение строки определенная вещь все же. std::string имеет конструктора, берущего один аргумент, который принимает char const*:

// simplified to a normal class declaration. std::string actually
// is a template instantiation. 
class string {
public:
    string(char const* str) {
        // copy over...
    }
};

Теперь Вы видите, что это имеет конструктора, берущего указатель на символ (символы). Так, чтобы это могло принять строковый литерал. Я думаю, что следующий случай очевиден затем:

string s("hello");

Это вызовет конструктора непосредственно и инициализирует s таким образом. Это называют прямой инициализацией.

Другой способ инициализировать переменную называют инициализацией копии. В Стандарте говорится для случая инициализации копии, где инициализатор не имеет типа объекта, это инициализирует, инициализатор преобразовывается в надлежащий тип.

// uses copy initialization
string s = "hello";

Во-первых, давайте заявим типы

  • s имеет станд. типа:: строка
  • "hello" массив, который в этом случае снова обрабатывается как указатель. Мы для этого рассмотрим это как char const*.

Компилятор ищет два способа сделать преобразование.

  • Есть ли в станд. конструктор преобразования:: строка?
  • Делает инициализатор, имеет тип, который имеет функцию оператора преобразования, возвращающуюся a std::string?

Это создаст временный файл std::string одним из тех путей, который затем используется для инициализации объекта s при помощи std::stringконструктор копии. И это видит std::string имеет конструктора преобразования, который принимает инициализатор. Таким образом, это использует его. В конце это - эффективно то же как

std::string s(std::string("hello"));

Обратите внимание, что форма, которая используется в Вашем примере, который инициировал все это

std::string s = "hello";

определяет неявное преобразование. Можно отметить конструктора, берущего char const* как явный для Ваших типов, если Вы задаетесь вопросом о правилах инициализации для Вашего материала, и он не позволит использовать соответствующего конструктора в качестве конструктора преобразования больше:

class string {
public:
    explicit string(char const* str) {
        // copy over...
    }
};

С этим, инициализируя его с помощью a copy initialization и a char const* на самом деле запрещается теперь (и в различных других местах)!

Теперь, это было то, если компилятор не поддерживает elision временных файлов в различных местах. Компилятору позволяют предположить, что конструктор копии копирует в этом контексте, и может устранить дополнительную копию временной строки и вместо этого создать временный станд.:: представьте в виде строки непосредственно в инициализированный объект. Однако конструктор копии должен быть доступным в частности. Так, инициализация копии недопустима, если Вы делаете это

class string {
public:
    explicit string(char const* str) {
        // copy over...
    }

private: // ugg can't call it. it's private!
    string(string const&);
};

Теперь на самом деле только прямой случай инициализации допустим.

21
ответ дан 3 December 2019 в 14:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: