Прямой доступ к переменной-члену через свойство - PullRequest
1 голос
/ 16 ноября 2009

Я задаю этот вопрос с производительностью в качестве основного вопроса. Но я хотел бы знать другие возможные преимущества / недостатки для обоих подходов.

Вопрос: поскольку свойства преобразуются в методы в IL, может ли существенное снижение производительности быть вызвано, если свойства вызываются вместо прямого доступа к полям (из класса)?

Я разрабатываю класс преобразования (PersonalizationConstructor), цель которого - «создать сущность домена» из IDataReader.

Я думаю принять IDataReader в конструкторе этого класса (PersonalizationConstructor) и иметь защищенные виртуальные свойства для возврата данных из набора записей IDataReader; как:

protected virtual string ProductFilterCriteria
{
    get;
    set;
}

Я мог бы иметь более 15 свойств в одном классе для этой реализации. Таким образом, свойство может быть переопределено, чтобы проверить, имеет ли набор записей поле «XXX» перед доступом из набора записей (я не хочу иметь такую ​​проверку как реализацию по умолчанию для всех).

Хорошо ли иметь 15+ виртуальных свойств в классе для реализации описанного выше случая?


Пожалуйста, не зацикливайтесь на IDataReader. Моя главная забота:

Поскольку свойства преобразуются в методы в IL, может ли быть значительная производительность штраф при вызове свойств вместо прямого доступа к полям (изнутри класса)?

У меня было бы что-то вроде этого:

class MainSite
{
    protected virtual string ProductFilterCriteria
    {
        get
        {           
            return _source["ProductFilterCriteria"];
        }
    }

    protected virtual string Abc
    {
        get
        {
            return _source["Abc"];
        }
    }

    protected virtual string Def
    {
        get
        {
            return _source["Def"];
        }
    }

    ..... many properties
}

class VirtualSite : MainSite
{
    protected override string ProductFilterCriteria
    {
        get
        {
            return null;
        }
    }
}

Ответы [ 3 ]

2 голосов
/ 16 ноября 2009

Как всегда, прежде чем принимать проектные решения, основанные на производительности, измерьте ее!

Предполагая, что данные поступают из реляционной базы данных, я строго подозреваю, что сам запрос (и связанные с ним преобразования, сетевой ввод-вывод и т. Д.) Будет доминировать в производительности.

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

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

1 голос
/ 16 ноября 2009

Возможно, вы захотите принять IDataRecord, а не IDataReader, поскольку это «базовый тип», который описывает часть DataReader, о которой вы позаботитесь.

В противном случае я бы просто использовал свойства. Все будет хорошо. Я бы не пометил их как "виртуальные". Скорее всего, этот тип на самом деле не предназначен для наследования, и, если это так, вероятно, эти свойства не следует трогать.

1 голос
/ 16 ноября 2009

Установка или извлечение свойства, которое реализовано с помощью синтаксиса свойства C # 3.0 или в старом стиле с полем, может (но не обязательно будет) оптимизироваться JIT. Это означает, что любые оптимизации в этом отношении не будут измеримы или даже могут привести к обратным результатам.

Вы говорите о свойствах, которые принимают тип класса (в отличие от примитивного типа, например int из float). Затраты на эти классы (ctor) или время, затрачиваемое на выполнение совершенно разных вещей (вы упомянули IDataReader, который я предполагаю, читает данные, что дорого), намного больше, чем возможные 1 или 2 µ-операции, которые вы могли бы обезопасить с помощью меняется от собственности к полю. На что я нахожусь: это как 0,001% прибыли, если даже.

Другими словами: хотя в очень редких ситуациях, когда вы находитесь во внутреннем цикле и должны выживать каждую микросекунду, вы можете пересмотреть этот выбор. В любых других ситуациях: используйте gettors / settors.

PS: читая другой ответ на этот вопрос. заставляет меня думать, что я, возможно, неправильно понял. Если это так, просто оставьте комментарий

РЕДАКТИРОВАТЬ: Джон С. упоминает, что виртуальные свойства не оптимизированы, это правильно. Но сюжетная линия по второстепенной прибыли остается неизменной

...