Для Firebase Hosting документация по переадресации и перезаписи приведена здесь: https://www.firebase.com/docs/hosting/guide/url-redirects-rewrites.html
Оттуда:
Используйте переписывание, когда вы хотите показывать один и тот же контент для нескольких URL-адресов. Rewrites особенно полезны при сопоставлении с образцом, так как вы можете принять любой URL-адрес, соответствующий шаблону, и позволить клиентскому коду решить, что отображать.
blockquote>Вероятно, вы ищете первый переписать sample на этой странице:
rewrites": [ { "source": "**", "destination": "/index.html" } ]
Это инструкция для веб-сервера, которая будет обслуживать
/index.html
для любого входящего запроса, независимо от того, какой путь.
Прямой ответ - да, это нормально.
Многие люди бросили разные идеи о том, как улучшить скорость, но, похоже, есть довольно много разногласий по поводу того, какой из них наиболее эффективен. Я решил написать программу для быстрого тестирования, чтобы получить хоть какое-то представление о том, какие методы что делают.
#include <iostream>
#include <string>
#include <sstream>
#include <time.h>
#include <iomanip>
#include <algorithm>
#include <iterator>
#include <stdio.h>
char fmt[] = "%s\n";
static const int count = 3000000;
static char const *const string = "This is a string.";
static std::string s = std::string(string) + "\n";
void show_time(void (*f)(), char const *caption) {
clock_t start = clock();
f();
clock_t ticks = clock()-start;
std::cerr << std::setw(30) << caption
<< ": "
<< (double)ticks/CLOCKS_PER_SEC << "\n";
}
void use_printf() {
for (int i=0; i<count; i++)
printf(fmt, string);
}
void use_puts() {
for (int i=0; i<count; i++)
puts(string);
}
void use_cout() {
for (int i=0; i<count; i++)
std::cout << string << "\n";
}
void use_cout_unsync() {
std::cout.sync_with_stdio(false);
for (int i=0; i<count; i++)
std::cout << string << "\n";
std::cout.sync_with_stdio(true);
}
void use_stringstream() {
std::stringstream temp;
for (int i=0; i<count; i++)
temp << string << "\n";
std::cout << temp.str();
}
void use_endl() {
for (int i=0; i<count; i++)
std::cout << string << std::endl;
}
void use_fill_n() {
std::fill_n(std::ostream_iterator<char const *>(std::cout, "\n"), count, string);
}
void use_write() {
for (int i = 0; i < count; i++)
std::cout.write(s.data(), s.size());
}
int main() {
show_time(use_printf, "Time using printf");
show_time(use_puts, "Time using puts");
show_time(use_cout, "Time using cout (synced)");
show_time(use_cout_unsync, "Time using cout (un-synced)");
show_time(use_stringstream, "Time using stringstream");
show_time(use_endl, "Time using endl");
show_time(use_fill_n, "Time using fill_n");
show_time(use_write, "Time using write");
return 0;
}
Я запускал ее в Windows после компиляции с VC ++ 2013 (как x86, так и x64 версии). Результат одного прогона (с перенаправлением вывода в файл на диске) выглядел следующим образом:
Time using printf: 0.953
Time using puts: 0.567
Time using cout (synced): 0.736
Time using cout (un-synced): 0.714
Time using stringstream: 0.725
Time using endl: 20.097
Time using fill_n: 0.749
Time using write: 0.499
Как и ожидалось, результаты различаются, но есть несколько моментов, которые я нашел интересными:
Я недавно отредактировал код, чтобы принудительно вызвать printf
. Андерс Касеорг любезно указал, что g ++
распознает конкретную последовательность printf ("% s \ n" , foo);
эквивалентно put (foo);
и соответственно генерирует код (т. е. генерирует код для вызова put
вместо printf
) .Перенос строки формата в глобальный массив и передача ее в качестве строки формата дает идентичный вывод, но заставляет его генерировать через printf
вместо put
. Конечно, это 'Возможно, когда-нибудь они тоже смогут оптимизировать это, но, по крайней мере, на данный момент (g ++ 5.1) тест с g ++ -O3 -S
подтверждает, что он действительно вызывает printf
(где предыдущий код, скомпилированный для вызова , помещает
).
Ну, я не могу придумать никакой причины для использования cout Если честно. Совершенно безумно иметь огромный громоздкий шаблон для чего-то настолько простого, что будет в каждом файле. Кроме того, похоже, что он разработан так, чтобы печатать как можно медленнее, и после миллионного раза ввода <<<<, а затем ввода значения между ними и случайного получения чего-то lik> variableName >>> Я больше не хочу этого делать .
Не говоря уже о том, что если вы включите пространство имен std, мир в конечном итоге взорвется, а если вы этого не сделаете, ваша нагрузка на набор текста станет еще более нелепой.
Однако мне тоже не очень нравится printf. Для меня, решение состоит в том, чтобы создать свой собственный конкретный класс, а затем вызвать в нем все, что необходимо для io. Тогда у вас может быть действительно простой io любым способом и с любой реализацией, которую вы хотите, с любым форматированием, которое вы хотите, и т.д. (обычно вы хотите, чтобы числа с плавающей запятой всегда были односторонними, например, а не форматировали их 800 способов без причины, поэтому поместите в форматировании при каждом звонке - это шутка).
Так что все, что я печатаю, это что-то вроде dout + "Это более разумно, чем" + cPlusPlusMethod + "из" + debugIoType + ". По крайней мере, IMO"; dout ++;
но вы можете получить все, что хотите. При большом количестве файлов удивительно, насколько это улучшает и время компиляции.
Кроме того, нет ничего плохого в смешивании C и C ++, это должно быть сделано разумно, и если вы используете вещи, которые вызывают проблемы с использованием C в Во-первых, можно с уверенностью сказать, что меньше всего вас беспокоят проблемы, связанные с смешиванием C и C ++.
Не беспокойтесь о производительности между printf
и cout
. Если вы хотите повысить производительность, отделите форматированный вывод от неформатированного.
put ("Hello World \ n")
намного быстрее, чем printf ("% s", "Hellow World \ n")
. (В первую очередь из-за накладных расходов на форматирование). После того, как вы изолировали форматированный текст от обычного текста, вы можете использовать такие приемы, как:
const char hello[] = "Hello World\n";
cout.write(hello, sizeof(hello) - sizeof('\0'));
Чтобы ускорить форматированный вывод, хитрость заключается в том, чтобы выполнить все форматирование в строку, а затем использовать вывод блока со строкой (или буфером):
const unsigned int MAX_BUFFER_SIZE = 256;
char buffer[MAX_BUFFER_SIZE];
sprintf(buffer, "%d times is a charm.\n", 5);
unsigned int text_length = strlen(buffer) - sizeof('\0');
fwrite(buffer, 1, text_length, stdout);
Чтобы еще больше повысить производительность вашей программы, уменьшите количество вывода. Чем меньше вы выводите, тем быстрее будет ваша программа. Побочным эффектом будет уменьшение размера исполняемого файла.
Также обратите внимание, что поток C ++ синхронизируется с потоком C.
Таким образом, он выполняет дополнительную работу, чтобы оставаться в синхронизации.
Еще одна вещь, на которую следует обратить внимание, - убедиться, что вы сбрасываете потоки равного количества. Если вы постоянно сбрасываете поток в одной системе, а не в другой, это определенно повлияет на скорость тестов.
Прежде чем предположить, что одна из них быстрее другой, вам следует:
Вы можете дополнительно повысить производительность printf
, увеличив размер буфера для stdout
:
setvbuf (stdout, NULL, _IOFBF, 32768); // any value larger than 512 and also a
// a multiple of the system i/o buffer size is an improvement
Количество обращений к операционной системе для выполнение ввода-вывода почти всегда является самым дорогим компонентом и ограничителем производительности.
Конечно, если вывод cout
смешивается с stdout
, очистка буфера не справляется с этой целью увеличение буфера размер.
Вы можете использовать sync_with_stdio
, чтобы ускорить ввод-вывод C ++.
cout.sync_with_stdio(false);
Должен улучшить производительность вывода с помощью cout
.
Мои книги по C ++ рекомендовали не смешивать методы C ++ и C, к сведению. Я почти уверен, что функции C нарушают состояние, ожидаемое / удерживаемое C ++.
Отправка std::endl
в поток добавляет newline
и смывает поток. Последующее обращение к cout.flush()
является излишним. Если это было сделано при синхронизации cout
с printf
, то вы не сравнивали яблоки с яблоками.
По умолчанию стандартные выходные потоки C и C ++ синхронизируются, поэтому запись в один из них приводит к сбросу другого, поэтому явные сбросы не нужны.