几个月前,我们发布了 Encore.ts — TypeScript 的开源后端框架。
由于已经有很多框架,我们想分享一些我们做出的不常见的设计决策以及它们如何带来显着的性能数据。
性能基准
我们之前发布的基准测试显示 Encore.ts 比 Express 快 9 倍,比 Fastify 快 2 倍。
这次我们将 Encore.ts 与 ElysiaJS 和 Hono 这两个现代高性能 TypeScript 框架进行了基准测试。
我们对带有和不带有模式验证的每个框架进行了基准测试,使用 TypeBox 与 ElsyiaJS 和 Hono 进行验证,因为它是这些框架原生支持的验证库。 (Encore.ts 有自己的内置类型验证,可以端到端工作。)
对于每个基准测试,我们都采取了五次运行的最佳结果。每次运行都是通过 150 个并发工作线程发出尽可能多的请求来执行,时间超过 10 秒。负载生成是使用 oha 执行的,oha 是一个基于 Rust 和 Tokio 的 HTTP 负载测试工具。
废话不多说,让我们看看数字!
每秒请求数:使用类型验证时,Encore.ts 比 ElysiaJS 和 Hono 快 3 倍
(查看 GitHub 上的基准代码。)
除了性能之外,Encore.ts 在实现这一点的同时还保持了与 Node.js100% 的兼容性
。工作原理:异常设计决策
这怎么可能?通过我们的测试,我们确定了性能的三个主要来源,所有这些都与 Encore.ts 的底层工作方式有关。
1. Encore.ts 是多线程的,由 Rust 运行时提供支持
Node.js 使用单线程事件循环运行 JavaScript 代码。尽管其具有单线程性质,但在实践中它具有相当大的可扩展性,因为它使用非阻塞 I/O 操作,并且底层 V8 JavaScript 引擎(也为 Chrome 提供动力)经过了极其优化。
但是你知道什么比单线程事件循环更快吗?多线程。
Encore.ts 由两部分组成:
- 使用 Encore.ts 编写后端时使用的 TypeScript SDK。
- 高性能运行时,具有用 Rust 编写的多线程异步事件循环(使用 Tokio 和 Hyper)。
Encore Runtime 处理所有 I/O,例如接受和处理传入的 HTTP 请求。它作为一个完全独立的事件循环运行,利用底层硬件支持的尽可能多的线程。
请求被完全处理和解码后,它会被移交给 Node.js 事件循环,然后从 API 处理程序获取响应并将其写回客户端。
(在你说之前:是的,我们在你的事件循环中放置了一个事件循环,这样你就可以在事件循环的同时进行事件循环。)
2. Encore.ts 预先计算请求模式
Encore.ts,顾名思义,是专为 TypeScript 设计的。但您实际上无法运行 TypeScript:它首先必须通过剥离所有类型信息来编译为 JavaScript。这意味着运行时类型安全更难实现,这使得验证传入请求之类的事情变得困难,导致像 Zod 这样的解决方案在运行时定义 API 模式变得流行。
Encore.ts 的工作方式有所不同。通过 Encore,您可以使用本机 TypeScript 类型定义类型安全的 API:
import { api } from "encore.dev/api"; interface BlogPost { id: number; title: string; body: string; likes: number; } export const getBlogPost = api( { method: "GET", path: "/blog/:id", expose: true }, async ({ id }: { id: number }) => Promise<blogpost> { // ... }, ); </blogpost>
Encore.ts 然后解析源代码以了解每个 API 端点期望的请求和响应模式,包括 HTTP 标头、查询参数等。然后,对架构进行处理、优化并存储为 Protobuf 文件。
当 Encore Runtime 启动时,它会读取此 Protobuf 文件并预先计算请求解码器和响应编码器,并使用每个 API 端点期望的确切类型定义,针对每个 API 端点进行优化。事实上,Encore.ts 甚至直接在 Rust 中处理请求验证,确保无效请求永远不必接触 JS 层,从而减轻许多拒绝服务攻击。
Encore 对请求模式的理解从性能角度来看也证明是有益的。像 Deno 和 Bun 这样的 JavaScript 运行时使用与 Encore 基于 Rust 的运行时类似的架构(事实上,Deno 也使用 Rust Tokio Hyper),但缺乏 Encore 对请求模式的理解。因此,他们需要将未处理的 HTTP 请求交给单线程 JavaScript 引擎执行。
Encore.ts, on the other hand, handles much more of the request processing inside Rust, and only hands over the decoded request objects. By handling much more of the request life-cycle in multi-threaded Rust, the JavaScript event-loop is freed up to focus on executing application business logic instead of parsing HTTP requests, yielding an even greater performance boost.
3. Encore.ts integrates with infrastructure
Careful readers might have noticed a trend: the key to performance is to off-load as much work from the single-threaded JavaScript event-loop as possible.
We've already looked at how Encore.ts off-loads most of the request/response lifecycle to Rust. So what more is there to do?
Well, backend applications are like sandwiches. You have the crusty top-layer, where you handle incoming requests. In the center you have your delicious toppings (that is, your business logic, of course). At the bottom you have your crusty data access layer, where you query databases, call other API endpoints, and so on.
We can't do much about the business logic — we want to write that in TypeScript, after all! — but there's not much point in having all the data access operations hogging our JS event-loop. If we moved those to Rust we'd further free up the event loop to be able to focus on executing our application code.
So that's what we did.
With Encore.ts, you can declare infrastructure resources directly in your source code.
For example, to define a Pub/Sub topic:
import { Topic } from "encore.dev/pubsub"; interface UserSignupEvent { userID: string; email: string; } export const UserSignups = new Topic<usersignupevent>("user-signups", { deliveryGuarantee: "at-least-once", }); // To publish: await UserSignups.publish({ userID: "123", email: "hello@example.com" }); </usersignupevent>
"So which Pub/Sub technology does it use?"
— All of them!
The Encore Rust runtime includes implementations for most common Pub/Sub technologies, including AWS SQS+SNS, GCP Pub/Sub, and NSQ, with more planned (Kafka, NATS, Azure Service Bus, etc.). You can specify the implementation on a per-resource basis in the runtime configuration when the application boots up, or let Encore's Cloud DevOps automation handle it for you.
Beyond Pub/Sub, Encore.ts includes infrastructure integrations for PostgreSQL databases, Secrets, Cron Jobs, and more.
All of these infrastructure integrations are implemented in the Encore.ts Rust Runtime.
This means that as soon as you call .publish(), the payload is handed over to Rust which takes care to publish the message, retrying if necessary, and so on. Same thing goes with database queries, subscribing to Pub/Sub messages, and more.
The end result is that with Encore.ts, virtually all non-business-logic is off-loaded from the JS event loop.
In essence, with Encore.ts you get a truly multi-threaded backend "for free", while still being able to write all your business logic in TypeScript.
Conclusion
Whether or not this performance is important depends on your use case. If you're building a tiny hobby project, it's largely academic. But if you're shipping a production backend to the cloud, it can have a pretty large impact.
Lower latency has a direct impact on user experience. To state the obvious: A faster backend means a snappier frontend, which means happier users.
Higher throughput means you can serve the same number of users with fewer servers, which directly corresponds to lower cloud bills. Or, conversely, you can serve more users with the same number of servers, ensuring you can scale further without encountering performance bottlenecks.
While we're biased, we think Encore offers a pretty excellent, best-of-all-worlds solution for building high-performance backends in TypeScript. It's fast, it's type-safe, and it's compatible with the entire Node.js ecosystem.
And it's all Open Source, so you can check out the code and contribute on GitHub.
Or just give it a try and let us know what you think!
以上がEncore.ts — ElysiaJS や Hono よりも高速の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

PythonとJavaScriptの主な違いは、タイプシステムとアプリケーションシナリオです。 1。Pythonは、科学的コンピューティングとデータ分析に適した動的タイプを使用します。 2。JavaScriptは弱いタイプを採用し、フロントエンドとフルスタックの開発で広く使用されています。この2つは、非同期プログラミングとパフォーマンスの最適化に独自の利点があり、選択する際にプロジェクトの要件に従って決定する必要があります。

PythonまたはJavaScriptを選択するかどうかは、プロジェクトの種類によって異なります。1)データサイエンスおよび自動化タスクのPythonを選択します。 2)フロントエンドとフルスタック開発のためにJavaScriptを選択します。 Pythonは、データ処理と自動化における強力なライブラリに好まれていますが、JavaScriptはWebインタラクションとフルスタック開発の利点に不可欠です。

PythonとJavaScriptにはそれぞれ独自の利点があり、選択はプロジェクトのニーズと個人的な好みに依存します。 1. Pythonは、データサイエンスやバックエンド開発に適した簡潔な構文を備えた学習が簡単ですが、実行速度が遅くなっています。 2。JavaScriptはフロントエンド開発のいたるところにあり、強力な非同期プログラミング機能を備えています。 node.jsはフルスタックの開発に適していますが、構文は複雑でエラーが発生しやすい場合があります。

javascriptisnotbuiltoncorc;それは、解釈されていることを解釈しました。

JavaScriptは、フロントエンドおよびバックエンド開発に使用できます。フロントエンドは、DOM操作を介してユーザーエクスペリエンスを強化し、バックエンドはnode.jsを介してサーバータスクを処理することを処理します。 1.フロントエンドの例:Webページテキストのコンテンツを変更します。 2。バックエンドの例:node.jsサーバーを作成します。

PythonまたはJavaScriptの選択は、キャリア開発、学習曲線、エコシステムに基づいている必要があります。1)キャリア開発:Pythonはデータサイエンスとバックエンド開発に適していますが、JavaScriptはフロントエンドおよびフルスタック開発に適しています。 2)学習曲線:Python構文は簡潔で初心者に適しています。 JavaScriptの構文は柔軟です。 3)エコシステム:Pythonには豊富な科学コンピューティングライブラリがあり、JavaScriptには強力なフロントエンドフレームワークがあります。

JavaScriptフレームワークのパワーは、開発を簡素化し、ユーザーエクスペリエンスとアプリケーションのパフォーマンスを向上させることにあります。フレームワークを選択するときは、次のことを検討してください。1。プロジェクトのサイズと複雑さ、2。チームエクスペリエンス、3。エコシステムとコミュニティサポート。

はじめに私はあなたがそれを奇妙に思うかもしれないことを知っています、JavaScript、C、およびブラウザは正確に何をしなければなりませんか?彼らは無関係であるように見えますが、実際、彼らは現代のウェブ開発において非常に重要な役割を果たしています。今日は、これら3つの間の密接なつながりについて説明します。この記事を通して、JavaScriptがブラウザでどのように実行されるか、ブラウザエンジンでのCの役割、およびそれらが協力してWebページのレンダリングと相互作用を駆動する方法を学びます。私たちは皆、JavaScriptとブラウザの関係を知っています。 JavaScriptは、フロントエンド開発のコア言語です。ブラウザで直接実行され、Webページが鮮明で興味深いものになります。なぜJavascrを疑問に思ったことがありますか


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

WebStorm Mac版
便利なJavaScript開発ツール

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール
