#c# #arrays #performance
#c# #массивы #Производительность
Вопрос:
Есть ли недостатки в производительности, когда я использую одноэлементный массив вместо простой переменной?
У меня есть базовый класс, из которого происходит множество других классов. Этот базовый класс предоставляет Value
свойство типа object .
Теперь я должен также поддерживать многозначные версии большинства классов. Таким образом, я думал о том, чтобы изменить protected object value
на protected object[] value
и использовать массив, даже если требуется только одно значение.
Я знаю длину массива в конструкторе, поэтому в случае экземпляров с одним значением длина массива равна 1.
Поскольку во время выполнения обычно существует множество экземпляров (до нескольких тысяч, в зависимости от количества пользователей) Я очень обеспокоен производительностью.
Итак, мой вопрос: вызовет ли это изменение с простой переменной на массив заметное изменение производительности или это вообще плохой дизайн?
Я думал о создании класса-оболочки, который допускает несколько значений, но классы тесно связаны через ссылки и события, так что это было бы неуклюже в использовании и обслуживании.
Отредактируйте, чтобы уточнить:
Цель базового класса в основном заключается в предоставлении интерфейса. Другие классы используют Value
свойство, именно поэтому оно определено в базовом классе. Сама переменная была определена только в базовом классе, поэтому мне не нужно определять ее в каждом производном классе (тип всегда object).
Многозначное расширение требуется не потому, что существуют производные классы, которым требуется более одного значения, а потому, что будет контекстно-зависимая среда (не знаю, как сформулировать это лучше) и классам нужно запоминать значение для каждого контекста.
Например, думайте об этом как о методе итернационализации (не в моем случае, просто в качестве примера).
Класс представляет слово, и в зависимости от языка, Value
это слово на соответствующем языке.
Помещая всю многозначную логику в базовый класс, производные классы могут продолжать работать так, как они всегда работали (используя Value
свойство), а базовый класс определяет, какое значение использовать.
Надеюсь, это немного прояснит ситуацию.
Комментарии:
1. Я предлагаю вам не думать об этом, пока у вас действительно не возникнет проблема с производительностью. Смотрите также: Преждевременная оптимизация
2. Я не видел ничего, что заставляло бы меня подозревать снижение сложности сверх того, что для вас сделает вывод из Object . Какова цель / задача этого базового класса?
3. Базовый класс предоставляет множество функций, которые я не описал здесь, потому что я думал, что это не имеет отношения к вопросу. Он объявляет и предоставляет реализацию по умолчанию для нескольких событий, объявляет несколько абстрактных методов и т.д. Мне пришлось бы подробно описать всю систему, что, я думаю, не обязательно.
Ответ №1:
Нет: объем накладных расходов, безусловно, не был бы заметен. Если это уменьшает сложность кода, то это хорошая идея.
Комментарии:
1. Вопрос в том, хороший ли это дизайн, так что напрашивается только вопрос: как подобная база снижает сложность? Исходя из приведенной информации, я бы сказал, что на данный момент это, вероятно, увеличивает сложность
2. Я согласен, что эта реализация кажется более сложной для чтения. Это, конечно, было бы не очень интуитивно для меня. Я думаю, было бы важно знать, работает ли оригинальный плакат над сольным или групповым проектом. Если проект групповой / с открытым исходным кодом, я могу возразить против того, чтобы делать это таким образом. Если соло… ну, похоже, он вложил в это так много мыслей, что это не покажется ему сложным.
3. Сложность программного обеспечения не так субъективна, как принято считать. Дейкстра , Википедия ( случайное против существенного )
4. Я, конечно, не имел в виду, что сложность кода — это то, что этот парень думает. Все, что я имел в виду, это то, что если это сольный проект, и он прекрасно понимает один способ сделать это, а не совсем другой, тогда следует выбрать первый способ.
5. Существует множество операций, для которых требуется класс, производный от «базового класса», поэтому мне нужен только этот тип. Я не буду создавать 10 методов, которые делают то же самое, только с другим типом параметра. Таким образом, базовый класс и
Value
свойство, которое является одним из немногих свойств, необходимых для множества операций. Я бы «спрятал» массив от производных классов, чтобы они продолжали работать соValue
свойством, не зная (или заботясь), являются ли они однозначными или многозначными. В случае многозначности только 1 значение за раз (а именно «текущее») должно представлять интерес для производных классов.
Ответ №2:
Я думаю, было бы более требовательно к производительности, если бы преобразовать массив в одну переменную и наоборот. Я был бы не против иметь массив с возможностью расширения одним значением!
Ответ №3:
Это увеличивает накладные расходы, но я сомневаюсь, что это будет заметно при «нормальных» обстоятельствах (например, не в замкнутом цикле).
Ответ №4:
Зачем нужен (а) глобальный базовый класс (б), который также предоставляет хранилище переменных?
Это похоже на … ненужная перенастройка (или … плохой дизайн, если вы предпочитаете). Я, конечно, не знаю никакого контекста, но я предлагаю больше в этом направлении:
public interface IValueProvider<out T> /* : IComparable<T>, IEquatable... etc */
{
T Value { get; /*protected?*/ set; }
}
Если вы настаиваете, у вас могут быть помощники по реализации, например, так:
public class ValueProviderClass<T> : IValueProvider<T>
where T : class, new()
{
ValueProviderClass() { Value = new T(); }
}
Конечно, также структуры могут реализовать интерфейс, предоставляя еще больше возможностей для оптимизации производительности, если возникнет необходимость в будущем (однако типы значений не смогут прозрачно выводиться из «базового» valuetype, потому что среда CLR этого не допускает)
Обратите внимание на использование ковариации для обеспечения совместимости с IValueProvider, например
Надеюсь, эта идея поможет вам развить более рациональное мышление
Ответ №5:
Не видя вашего кода, у меня возникает ощущение, что можно поставить под сомнение дизайн. У вас есть базовый класс, который может содержать одно или несколько «значений» произвольного типа? Обычно я бы использовал базовый класс для содержания свойств и / или функциональности, которые являются общими для производных типов, но если я замечаю, что базовый класс пытается «соответствовать всем возможным потребностям» производных классов, вероятно, пришло время провести рефакторинг. В этом случае ваш базовый класс мне кажется слишком общим.
При этом возможно, что ваша конкретная ситуация оправдывает дизайн. (И я не думаю, что вы заметили бы какое-либо снижение производительности.)
Ответ №6:
Почему бы не сделать класс универсальным и не указать тип значения при создании экземпляра класса?