Каковы издержки типа без данных? - PullRequest
9 голосов
/ 28 июня 2011

Я не хочу начинать пламенную войну с микрооптимизацией, но мне интересно кое о чем.

Каковы накладные расходы с точки зрения памяти и производительности при создании экземпляров типа, который не имеет встроенной функции?данные?

Например, простой класс, который реализует IComparer<T>, может содержать только метод Compare и не иметь свойств или полей.

class FooComprarer : IComparer<Foo>
{
    public int Compare (Foo x, Foo y) 
    {
        // blah, blah
    }
}

Типичный пример кода, который я видел, просто вызывает new FooComparer(), где бы ни понадобился один из них.

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

Ответы [ 3 ]

13 голосов
/ 28 июня 2011

Есть некоторые издержки, но они, вероятно, ничтожны по сравнению с тем, для чего вы собираетесь использовать компаратор.

В 32-разрядной и 64-разрядной системах этот экземпляр будет использовать 16 байт пространства кучи. Накладные расходы составляют два указателя, которые используют 8 байтов в 32-битной системе и 16 байтов в 64-битной системе. Однако диспетчер памяти в 32-разрядной системе не может выделить блоки размером менее 16 байтов, поэтому в блоке будет 8 неиспользуемых байтов.

Если вы многократно используете эти компараторы, вы можете оставить их в покое. Однако вам также следует учитывать, что недолговечные объекты вызывают гораздо меньшую нагрузку на управление памятью, чем долгоживущие объекты, поэтому вам придется многократно использовать компараторы, чтобы они того стоили, чтобы поддерживать их.

2 голосов
/ 28 июня 2011

Это только косвенно связано с вашим вопросом, но если вы используете C # 3.0 или выше, вы можете использовать этот шаблон:

public class AdhocComparer<T> : IComparer
{
    Func<T, T, int> comparer;

    AdhocComparer(Func<T, T, int> comparer)
    {

        this.comparer = comparer;

    }

    public int Compare (Foo x, Foo y) 
    {
        return comparer(x, y);
    }

}

И использовать так:

var fooComparer = new AdhocComparer<Foo>( (x, y) => /* do stuff */);

Таким образом, вам не нужно создавать класс для каждого типа IComparer, который вам нужен.

2 голосов
/ 28 июня 2011

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

Согласно http://www.simple -talk.com / dotnet / .net-framework / объект-накладные-скрытые-.net-память - стоимость размещения / :

В 32-битной системе каждый объект имеет 8-байтовый заголовок [...] В 64-битных системах ситуация хуже. Заголовок объекта увеличен до 16 байт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...