Почему пол () настолько медленный?

forEach всегда возвращает undefined, поэтому ваш map обратный вызов возвращает undefined, поэтому numbers будет заполнено undefined с.

Я думаю, что вы, вероятно, хотите вернуть телефонные номера (каждый number в массиве phoneNumbers каждой записи), а затем, возможно, сгладить результат:

const numbers = contacts.map(contact => contact.phoneNumbers.map(({number}) => number)).flat();

Array.prototype.flat ] является относительно новым, но легко заполняется.

Это настолько распространенная модель, что есть метод flatMap , чтобы сделать это за один раз:

const numbers = contacts.flatMap(contact => contact.phoneNumbers.map(({number}) => number));

Или просто простой цикл с push:

const numbers = [];
for (const {phoneNumbers} of contacts) {
    numbesr.push(...phoneNumbers.map(({number}) => number));
}

33
задан Peter Cordes 2 November 2018 в 06:55
поделиться

3 ответа

Несколько вещей делают пол медленнее, чем бросок, и предотвращают векторизацию.

Самый важный:

пол может изменять глобальное состояние. Если вы передаете значение, которое слишком велико, чтобы представлять его как целое число в формате с плавающей запятой, переменная errno будет установлена ​​в EDOM . Специальная обработка для NaN также выполняется. Все это относится к приложениям, которые хотят обнаружить случай переполнения и как-то справиться с ситуацией (не спрашивайте меня, как).

Обнаружение этих проблемных условий не простое и составляет более 90% времени выполнения пола , Фактическое округление дешево и может быть встроено / векторизовано. Также много кода, так что встраивание всей функции floor сделает вашу программу медленной.

Некоторые компиляторы имеют специальные флаги компилятора, которые позволяют компилятору оптимизировать некоторые из редко используемых правил c-стандарта. Например, GCC можно сказать, что вы вообще не заинтересованы в errno. Для этого передайте -fno-math-errno или -fast-math . ICC и VC могут иметь похожие флаги компилятора.

Кстати, вы можете выполнить свою собственную функцию пола, используя простые приведения. Вы просто должны обращаться с отрицательными и положительными случаями по-разному. Это может быть намного быстрее, если вам не нужна специальная обработка переполнений и NaN.

Кстати - вы можете выполнить свою собственную функцию пола, используя простые приведения. Вы просто должны обращаться с отрицательными и положительными случаями по-разному. Это может быть намного быстрее, если вам не нужна специальная обработка переполнений и NaN.

Кстати - вы можете выполнить свою собственную функцию пола, используя простые приведения. Вы просто должны обращаться с отрицательными и положительными случаями по-разному. Это может быть намного быстрее, если вам не нужна специальная обработка переполнений и NaN.

42
ответ дан 27 November 2019 в 18:01
поделиться

Да, floor () очень медленный на всех платформах, так как он должен реализовывать много поведения из спецификации IEEE fp. Вы не можете использовать его во внутренних циклах.

Я иногда использую макрос для аппроксимации floor ():

#define PSEUDO_FLOOR( V ) ((V) >= 0 ? (int)(V) : (int)((V) - 1))

Он не ведет себя точно так же, как floor () : например, floor (-1) == -1 но PSEUDO_FLOOR (-1) == -2 , но этого достаточно близко для большинства применений.

1
ответ дан 27 November 2019 в 18:01
поделиться
  1. Они не делают то же самое. Этаж () является функцией. Следовательно, его использование требует вызова функции, выделения кадра стека, копирования параметров и получения результата. Приведение не является вызовом функции, поэтому оно использует более быстрые механизмы (я полагаю, что оно может использовать регистры для обработки значений).
  2. Вероятно, floor () уже оптимизирован.
  3. Можете ли вы выжать из своего алгоритма больше производительности? Может быть, переключение строк и столбцов может помочь? Можете ли вы кешировать общие значения? Все ли оптимизации вашего компилятора включены? Можете ли вы переключить операционную систему? компилятор? Jon Bentley's Programming Pearls имеет большой обзор возможных оптимизаций.
-1
ответ дан 27 November 2019 в 18:01
поделиться
Другие вопросы по тегам:

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