Node.js быстрее, чем Go.
При тестировании производительности API на соответствие базе данных Timescale Postgres DB локально в контейнере Docker — это были созданные в разных фреймворках простые API-интерфейсы, которыми выполнялся поиск записи из более 100 миллионов записей, — обнаружилось, что в Go получается около 2000 запросов в секунду.
Удивительным было то, что в NestJS и Bun получается на 1000 больше. Как же так, ведь Go на голову выше?
Проблема заключалась в применении пул
Node.js быстрее, чем Go...
При тестировании производительности API на соответствие базе данных Timescale Postgres DB локально в контейнере Docker — это были созданные в разных фреймворках простые API-интерфейсы, которыми выполнялся поиск записи из более 100 миллионов записей, — обнаружилось, что в Go получается около 2000 запросов в секунду.
Удивительным было то, что в NestJS и Bun получается на 1000 больше. Как же так, ведь Go на голову выше?
Проблема заключалась в применении пула соединений, а не в установке ограничений на максимальные и незадействованные соединения. Этого нет во многих руководствах, посвященных пакету SQL для Go.
После установки ограничений стало получаться в 2–3 раза больше запросов в секунду на Go.
При поиске способа подключения к базе данных нашлось много примеров, таких как этот:
func NewPostgresStore() (*PostgresStore, error) {
godotenv.Load()
connStr := fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=%s sslmode=%s",
os.Getenv("HOST"), os.Getenv("PORT"), os.Getenv("DBUSER"), os.Getenv("DBNAME"), os.Getenv("DBPASS"), os.Getenv("SSLMODE"))
db, err := sql.Open("postgres", connStr)
if err != nil {
return nil, err
}following:
func NewPostgresStore() (*PostgresStore, error) {
godotenv.Load()
connStr := fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=%s sslmode=%s",
os.Getenv("HOST"), os.Getenv("PORT"), os.Getenv("DBUSER"), os.Getenv("DBNAME"), os.Getenv("DBPASS"), os.Getenv("SSLMODE"))
db, err := sql.Open("postgres", connStr)
if err != nil {
return nil, err
}
db.SetMaxOpenConns(20)
db.SetMaxIdleConns(20)
// defer db.Close()
if err := db.Ping(); err != nil {
return nil, err
}
return &PostgresStore {
db: db,
}, nil
}
Примеров определения пула соединений было куда меньше. Ведь это так же просто, как установить сразу после открытия соединения вот это:
// Открываем соединение с базой данных
db, err := sql.Open("postgres", connStr)
if err != nil {
return nil, err
}
// Устанавливаем для пула соединений лимит соединений
db.SetMaxOpenConns(20)
db.SetMaxIdleConns(20)
Поэкспериментируйте с этими значениями в поисках подходящих вашей базе данных с точки зрения производительности.
Тестирование производительности
Go без пула соединений:
Go с пулом соединений:
Nodejs с Nestjs:
Bun: