Что является более эффективным, случай переключения или std :: map

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

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

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
25
задан the_drow 24 December 2013 в 16:15
поделиться

6 ответов

Карта STL, поставляемая с Visual Studio 2008, даст вам O (log (n)) для каждого вызова функции, так как она скрывает древовидную структуру внизу. В современном компиляторе (в зависимости от реализации) оператор switch даст вам O (1), компилятор переводит его в какую-то таблицу поиска. В общем, переключение выполняется быстрее.

Однако , примите во внимание следующие факты:

Разница между картой и переключателем заключается в том, что: Карта может быть построена динамически, а переключатель - нет. Map может содержать любой произвольный тип в качестве ключа, в то время как switch очень ограничен примитивными типами C ++ (char, int, enum и т. Д.).

Кстати, вы можете использовать хэш-карту для достижения почти O (1 ) диспетчеризации (хотя, в зависимости от реализации хэш-таблицы, в худшем случае иногда может быть O (n)). Несмотря на то, что переключение все равно будет быстрее.

Править

Я пишу следующее только для удовольствия и в рамках обсуждения

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

Когда вы пишете код: Вы делите свои жетоны на две группы: одна группа будет очень часто использоваться, а другая - низкой. Вы также сортируете наиболее часто используемые токены. Для токенов с высокой частотой вы пишете серию if-else, в которой наиболее часто используемые токены идут первыми. для часто используемых low вы пишете оператор switch.

Идея состоит в том, чтобы использовать прогнозирование ветвления CPU, чтобы даже избежать другого уровня косвенного обращения (при условии, что проверка условий в операторе if почти не требует затрат). в большинстве случаев ЦП выберет правильную ветвь без какого-либо косвенного обращения. Однако будет немного случаев, когда ветка уйдет не в то место. В зависимости от характера вашего языка, по статистике, он может дать лучшую производительность.

Изменить : Из-за некоторых комментариев ниже, Изменено Предложение, говорящее, что компиляторы всегда переводят переключение на LUT.

22
ответ дан 28 November 2019 в 04:44
поделиться

Я бы посоветовал прочитать switch () vs. таблицу поиска? от Джоэла на Software. В частности, интересен такой ответ:

«Яркий пример того, как люди тратят время зря. пытаясь оптимизировать наименьшее важная вещь. "

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

В виртуальных машинах таблицы поиска, хранящие вычисленные адреса для вызова, обычно предпочтительнее коммутаторов. (прямая потоковая передача, или «метка как значения». напрямую вызывает адрес метки, хранящийся в таблице поиска). Это потому, что это позволяет при определенных условиях уменьшить неверное предсказание ветвления , что чрезвычайно дорого при длинном конвейере CPU (заставляет промывать конвейер). Однако это делает код менее переносимым.

Этот вопрос широко обсуждался в сообществе виртуальных машин, я бы посоветовал вам поискать научные статьи в этой области, если вы хотите узнать о нем больше. Эртл и Грегг написали отличную статью на эту тему в 2001 г. Поведение эффективных интерпретаторов виртуальных машин в современных архитектурах

Но, как уже упоминалось, я ' m почти уверен, что эти детали не имеют отношения к вашего кода. Это мелкие детали, и не стоит на них слишком зацикливаться. Интерпретатор Python использует переключатели, потому что они думают, что это делает код более читабельным. Почему бы вам не выбрать наиболее удобный вариант использования? Влияние на производительность будет довольно небольшим, вам лучше сосредоточиться на удобочитаемости кода;)

Изменить : Если это важно, использование хэш-таблицы всегда будет медленнее, чем таблица поиска. Для таблицы поиска вы используете типы перечисления для своих «ключей», и значение извлекается с помощью одного косвенного перехода. Это единичная сборочная операция. О (1). Для поиска в хэш-таблице сначала требуется вычислить хэш, а затем получить значение, что намного дороже.

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

Подводя итог, мы имеем:

  • cost (Hash_table) >> cost (direct_lookup_table)
  • cost (direct_lookup_table) ~ = cost (switch) if ваш компилятор переводит переключатели в таблицы поиска.
  • cost (switch) >> cost (direct_lookup_table) (O (N) vs O (1)), если ваш компилятор не переводит переключатели и не использует условные выражения, но я не могу представить, чтобы какой-либо компилятор делал это.
  • Но встроенная прямая потоковая передача делает код менее читаемым.
34
ответ дан 28 November 2019 в 04:44
поделиться

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

Чтобы получить быстрое переключение, ваши значения должны соответствовать следующему правилу: они должны быть последовательными, например 0,1,2,3,4. Вы можете пропустить некоторые значения, но такие вещи, как 0,1,2,34,43, вряд ли будут оптимизированы.

На самом деле возникает вопрос: так ли важна производительность в вашем приложении? И разве карта, динамически загружающая свои значения из файла, не будет более удобочитаемой и удобной в обслуживании вместо огромного оператора, охватывающего несколько страниц кода?

2
ответ дан 28 November 2019 в 04:44
поделиться

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

3
ответ дан 28 November 2019 в 04:44
поделиться

Вы не говорите, какой у вас тип токенов. Если они не целые, у вас нет выбора - переключатели работают только с целыми типами.

1
ответ дан 28 November 2019 в 04:44
поделиться

Стандарт C ++ ничего не говорит о производительности его требования, только наличие функциональности.

Подобные вопросы о том, что лучше, быстрее или эффективнее, бессмысленны, если вы не укажете, о какой реализации вы говорите. Например, обработка строк в определенной версии определенной реализации JavaScript была ужасной, но вы не можете экстраполировать это на особенность соответствующего стандарта.

Я бы даже сказал, что это не так. t имеет значение независимо от реализации, поскольку функциональные возможности, обеспечиваемые переключателем и std :: map , различны (хотя и перекрываются).

0
ответ дан 28 November 2019 в 04:44
поделиться
Другие вопросы по тегам:

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