Не пытайтесь зациклить асинхронные функции таким образом, так как это не требуется, и, конечно, не отправляйте ответы в цикле. Вместо этого вам следует .map()
список регулярных выражений для $in
:
router.post('/search-phrasing', (req, res) => {
const { phrasing } = req.body;
if (phrasing == undefined || ( typeof(phrasing) != 'string' ) ) {
console.error("phrasing is required as a string");
return res.end(); // really should have better error handling
}
const phrasingArray = phrasing.trim().split(' ');
Response.find({ entities: { $in: phrasingArray.map(e => RegExp(e)) })
.sort('phrasing')
.select('phrasing')
.then(suggestions => res.send(suggestions))
.catch(err => console.error(err));
})
Оператор $in
принимает массив аргументов для сопоставления. Также случается принимать регулярные выражения в качестве этих аргументов. Это в основном сокращение для оператора $or
, но всегда применяется к одному полю.
Попытка сделать это в противном случае - выполнить несколько операторов с базой данных, ожидая различных обещаний и пытаясь построить единый ответ из всего этого. Это просто не нужно, когда есть выражения запроса, которые уже обрабатывают это.
Также проверьте ваши типы ввода. Не думайте вслепую, что вы предоставили необходимые данные в тело POST. Проверьте наличие, как показано здесь, в противном случае вы получите исключения
Используйте лучший счетчик, доступный на вашей платформе, для переносимости используйте время (). Я использую QueryPerformanceCounter, но смотри комментарии в другом ответе.
Общие рекомендации:
Внутренний цикл должен работать как минимум примерно в 20 раз с разрешением ваших часов, чтобы сделать ошибку разрешения. <5%. (таким образом, при использовании time () ваш внутренний цикл должен работать не менее 20 секунд)
Повторите эти измерения, чтобы увидеть, согласуются ли они.
Я использую дополнительный внешний цикл , работающий десять раз и игнорирующий самое быстрое и самое медленное измерение для вычисления среднего и отклонения. Отклонение удобно при сравнении двух реализаций: если у вас один алгоритм, принимающий 2,0 мс +/- 5, а другой 2,2 +/- 0,5, то разница не будет существенной, чтобы назвать одну из них «быстрее». (Макс и мин все еще должны отображаться). Поэтому ИМХО правильное измерение производительности должно выглядеть примерно так:
10000 x 2.0 +/- 0.2 ms (min = 1.2, , max=12.6), 10 repetitions
Если вы знаете, что делаете, очистка кэша и настройка соответствия потоков могут сделать ваши измерения намного более надежными.
Однако, это не без пифалов. Чем «стабильнее» измерение, тем менее оно реалистично. Любая реализация будет сильно меняться со временем, в зависимости от состояния данных и кэша команд. Я ленив здесь, используя значение max = для оценки штрафа за первый запуск, этого может быть недостаточно для некоторых сценариев.
Если ваш Функция очень быстрая, хорошей практикой является определение времени цикла в цикле, а затем вычитание накладных расходов цикла.
Примерно так:
int i;
int limit=1000000;
int t0=getTime();
for(i=0; i < limit; ++i)
;
int t1=getTime();
int loopoverhead = t1-t0;
t0=getTime();
for(i=0; i < limit; ++i)
function();
t1=getTime();
double tfunction = (1.0/limit)*((t1-t0)-loopoverhead);
В системах Unix (Linux, Mac и т. Д.) Вы можете использовать утилиту time
, например:
$ time ./my_app
Вы можете просто использовать time () в своем коде для измерения с точностью до секунд. Тщательные тесты должны выполнять много итераций для точности, поэтому секунд должно быть достаточно много. Если вы используете linux, вы можете использовать утилиту времени, предоставленную командной строкой, например:
[john@awesome]$time ./loops.sh
real 0m3.026s
user 0m4.000s
sys 0m0.020s
Вы можете использовать функцию time ()
, чтобы получить таймер с разрешением в одну секунду. Если вам нужно больше разрешения, вы можете использовать gettimeofday ()
. Разрешение зависит от вашей операционной системы и библиотеки времени выполнения.
Рассматривали ли вы на самом деле использование профилировщика? Visual Studio Team System имеет один встроенный, но есть и другие, такие как VTune и GlowCode.
См. Также Какой самый лучший бесплатный профилировщик C ++ для Windows?
Я всегда использую boost :: timer или boost :: progress_timer .
псевдокод:
#include <boost/timer.hpp>
boost::timer t;
func1();
cout << "fun1: " << t.elapsed();
t.restart();
func2();
cout << "func2(): " << t.elapsed();
В Windows вы можете использовать высокопроизводительные счетчики для получения более точных результатов:
Вы можете использовать функцию QueryPerformanceFrequency ()
, чтобы получить число высокочастотных тиков за секунду и пользователя QueryPerformanceCounter ()
до и после функции, которую вы хотите синхронизировать.
Конечно, этот метод не переносим ...
Выполнить функцию несколько тысяч раз, чтобы получить точное измерение.
В событиях ОС могут преобладать события ОС. или другой случайный шум.
Если вы хотите проверить свою производительность, вам следует подумать об измерении времени процессора , а не реального времени , которое вы пытаетесь измерить сейчас. В противном случае вы можете получить довольно неточные значения, если какое-либо другое приложение, работающее в фоновом режиме, решит выполнить некоторые тяжелые вычисления одновременно. Нужные функции: GetProcessTimes в Windows и getrusage в Linux.
Также вам следует рассмотреть возможность использования профилировщиков, как предлагали другие.
Запустите его 1000 раз за 100 итераций * 10 итераций, где вы развернете внутренний цикл, чтобы минимизировать издержки. Затем секунды переводятся в миллисекунды.
Как уже отмечали другие, это хороший способ измерить, сколько времени это займет.
Однако, если вы также хотите, чтобы это заняло меньше времени, это другая цель, и нужна другая техника. Мой любимый это.
Что не так с clock ()
и CLOCKS_PER_SEC
? Они являются стандартными C89.
Что-то вроде (от MSDN):
long i = 6000000L;
clock_t start, finish;
double duration;
// Measure the duration of an event.
printf( "Time to do %ld empty loops is ", i );
start = clock();
while( i-- )
;
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf( "%2.1f seconds\n", duration );