Действительно ли закрытые классы предлагают преимущества в производительности?

В Python 2.6+ вы можете использовать io.open() , который по умолчанию ( builtin open() ) на Python 3:

import io

with io.open(filename, 'w', encoding=character_encoding) as file:
    file.write(unicode_text)

Возможно, было бы более удобно, если вам нужно постепенно писать текст (вам не нужно многократно называть unicode_text.encode(character_encoding)). В отличие от модуля codecs модуль io имеет правильную универсальную поддержку новых строк.

133
задан Lance Roberts 14 October 2008 в 19:53
поделиться

8 ответов

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

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

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

Вот одна ссылка, упоминая это: Меля вздор изолированное ключевое слово

55
ответ дан 24 November 2019 в 00:02
поделиться

<вне-темы-напыщенная-речь>

Я ненавижу запечатанные классы. Даже если выигрыши в производительности изумляют (относительно которого я сомневаюсь), они уничтожают объектно-ориентированную модель путем предотвращения повторного использования через наследование. Например, класс Потока изолируется. В то время как я вижу, что можно было бы хотеть, чтобы потоки были максимально эффективны, я могу также вообразить сценарии, где способность разделить Поток на подклассы обладала бы большими преимуществами. Авторы класса, если необходимо изолировать классы по причинам "производительности", обеспечивают интерфейс по крайней мере, таким образом, мы не имеем к переносить-и-заменять везде, что нам нужна функция, которую Вы забыли.

Пример: SafeThread должен был перенести класс Потока, потому что Поток изолируется и нет никакого интерфейса IThread; SafeThread автоматически захватывает необработанные исключения на потоках, чем-то абсолютно недостающем от класса Потока. [и не, события необработанного исключения не берут необработанные исключения во вторичных потоках].

</off-topic-rant>

4
ответ дан 24 November 2019 в 00:02
поделиться

Ответ не, запечатанные классы не работают лучше, чем неизолированный.

Проблема сводится call по сравнению с callvirt Коды операции IL. Call быстрее, чем callvirt, и callvirt главным образом используется, когда Вы не знаете, был ли объект разделен на подклассы. Таким образом, люди предполагают, что при изоляции класса, все коды операции изменятся от calvirts кому: calls и будет быстрее.

К сожалению, callvirt делает другие вещи, которые делают это полезным также, как проверка нулевые ссылки. Это означает, что, даже если класс изолируется, ссылка могла бы все еще быть нулевой и таким образом a callvirt необходим. Можно обойти это (не будучи должен изолировать класс), но это становится немного бессмысленным.

Использование структур call потому что они не могут быть разделены на подклассы и никогда не пустые.

Посмотрите этот вопрос для получения дополнительной информации:

Звоните и callvirt

138
ответ дан 24 November 2019 в 00:02
поделиться

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

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

3
ответ дан 24 November 2019 в 00:02
поделиться

@Vaibhav, какие тесты Вы выполняли для измерения уровня?

Я предполагаю, что нужно было бы использовать Ротор и развернуть в CLI и понять, как запечатанный класс улучшит производительность.

SSCLI (Ротор)
SSCLI: общая исходная общеязыковая инфраструктура

Общеязыковая инфраструктура (CLI) является стандартом ECMA, который описывает ядро Платформы.NET. Общий Источник CLI (SSCLI), также известный как Ротор, является сжатым архивом исходного кода к рабочей реализации CLI ECMA и спецификации языка C# ECMA, технологий в основе архитектуры.NET Microsoft.

2
ответ дан 24 November 2019 в 00:02
поделиться

Маркировка класса запечатанный не должна иметь производительности

Есть случаи, когда csc , возможно, придется испустить код операции callvirt вместо кода операции call . Однако мне кажется, что такие случаи редки.

И мне кажется, что JIT должна иметь возможность генерировать тот же вызов невиртуальной функции для callvirt , что и для вызова ], если он знает, что у этого класса нет подклассов (пока). Если существует только одна реализация метода, нет смысла загружать его адрес из vtable - просто вызовите эту реализацию напрямую. В этом отношении JIT может даже встроить функцию.

It ' Это небольшая игра со стороны JIT, потому что, если подкласс будет позже загружен, JIT придется отбросить этот машинный код и снова скомпилировать код, испуская настоящий виртуальный вызов. Я предполагаю, что на практике это случается нечасто.

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

4
ответ дан 24 November 2019 в 00:02
поделиться

Запустите этот код, и вы увидите, что закрытые классы работают в 2 раза быстрее:

class Program
{
    static void Main(string[] args)
    {
        Console.ReadLine();

        var watch = new Stopwatch();
        watch.Start();
        for (int i = 0; i < 10000000; i++)
        {
            new SealedClass().GetName();
        }
        watch.Stop();
        Console.WriteLine("Sealed class : {0}", watch.Elapsed.ToString());

        watch.Start();
        for (int i = 0; i < 10000000; i++)
        {
            new NonSealedClass().GetName();
        }
        watch.Stop();
        Console.WriteLine("NonSealed class : {0}", watch.Elapsed.ToString());

        Console.ReadKey();
    }
}

sealed class SealedClass
{
    public string GetName()
    {
        return "SealedClass";
    }
}

class NonSealedClass
{
    public string GetName()
    {
        return "NonSealedClass";
    }
}

вывод: Запечатанный класс: 00:00: 00.1897568 Класс NonSealed: 00: 00: 00.3826678

-10
ответ дан 24 November 2019 в 00:02
поделиться

Я считаю "герметичные" классы нормальным случаем, и у меня ВСЕГДА есть причина опустить ключевое слово "sealed".

Наиболее важными причинами для меня являются:

a) Лучшие проверки во время компиляции (приведение к нереализованным интерфейсам будет обнаружено во время компиляции, а не только во время выполнения)

и, главная причина:

b) Злоупотребление моими классами таким образом невозможно

Я хотел бы, чтобы Microsoft сделала "sealed" стандартом, а не "unsealed".

3
ответ дан 24 November 2019 в 00:02
поделиться
Другие вопросы по тегам:

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