209 votes

Performance de node.js vs .net

J’ai beaucoup lu sur Node.js rapide et pouvant accueillir de grandes quantités de charge. Quelqu'un at-il des signes de monde réel de cette vs autres cadres, en particulier de .net ? La plupart des articles que j’ai lu est anecdotique ou n’avez pas des comparaisons à .net.

Merci

397voto

Matt Dotson Points 3100

D'être RAPIDE et de la manipulation de beaucoup de CHARGE sont deux choses différentes. Un serveur qui est vraiment RAPIDE à servir une requête par seconde peut totalement croa si vous l'envoyez 500 requêtes par seconde (sous CHARGE).

Vous avez également à considérer statique (et caché) vs les pages dynamiques. Si vous êtes inquiet au sujet de pages statiques, IIS va probablement battre nœud, car IIS utilise en mode noyau de la mise en cache, ce qui signifie que les demandes que les demandes pour une page statique ne sont même pas sortir du noyau.

Je devine que vous êtes à la recherche pour une comparaison entre ASP.NET et le nœud. Dans cette bataille, après que tout a été compilé/interprété vous allez probablement être assez proche de la performance. Peut-être .NET est un peu plus RAPIDE ou peut-être le nœud est un peu plus RAPIDE, mais c'est probablement assez proche de ce que vous n'avez pas de soins. J'avais parié sur .NET, mais je ne sais pas pour sûr.

La place de ce nœud est vraiment impressionnant, c'est pour la manutention de la CHARGE. C'est là que les technologies sont vraiment différents. ASP.NET consacre un thread par la demande de son pool de threads, et une fois ASP.NET il a épuisé tous les threads disponibles demandes de commencer à la file d'attente. Si vous êtes à la portion "Hello World" des applications comme l'exemple par @shankar, alors cela pourrait ne pas beaucoup d'importance parce que les fils ne vont pas bloquer et vous allez être en mesure de gérer beaucoup de demandes avant de vous lancer des threads. Le problème avec la ASP.NET le modèle vient quand vous commencez à faire des demandes d'e/S qui bloque le thread (appel à un DB, faire une requête http à un service, lire un fichier à partir du disque). Ces demandes de blocage signifie que votre précieux fil de la piscine est de ne rien faire. Le plus bloquant que vous avez, le moins de CHARGE de votre ASP.NET application va être en mesure de servir.

Pour éviter ce blocage, vous utilisez I/O ports de fin qui n'exigent pas la tenue d'un fil pendant que vous attendez une réponse. ASP.NET prend en charge cela, mais malheureusement, beaucoup de cadres communs/bibliothèques .NET NE LE FONT PAS. Par exemple, ADO.NET prend en charge I/O ports de fin, mais l'Entity Framework ne les utilise pas. De sorte que vous pouvez construire une ASP.NET app qui est purement asynchrone et gère beaucoup de charge, mais la plupart des gens ne le font pas car il n'était pas aussi facile que la construction de celui qui est synchrone, et vous pourriez ne pas être en mesure d'utiliser certaines de vos parties préférées du cadre (comme linq to entities) si vous ne.

Le problème est que ASP.NET (et l' .NET Framework) a été créé pour être l'onu-opinions sur les e/s asynchrones..NET ne se soucie pas si vous écrivez synchrone ou asynchrone code, c'est au développeur de prendre cette décision. C'est en partie parce que le filetage et la programmation des opérations asynchrones a été pensé pour être "dur", et .NET voulu faire plaisir à tout le monde (les noobs et les experts). Il est devenu encore plus difficile parce que .NET a fini avec 3 ou 4 modèles différents pour faire asynchrone. .NET 4.5, est d'essayer de revenir en arrière et de rénover le .NET framework pour avoir un opiniâtre modèle autour async IO, mais il peut être un certain temps jusqu'à ce que les cadres que vous vous souciez réellement de la soutenir.

Les concepteurs de noeud sur l'autre main, faites un opiniâtre de choix pour TOUTES les e/S doivent être asynchrone. En raison de cette décision, le noeud les concepteurs ont également été en mesure de prendre la décision que chaque instance de nœud d'être mono-thread afin de minimiser fil de commutation, et qu'un thread juste d'exécuter du code qui avait été mis en file d'attente. Que pourrait être une nouvelle demande, il pourrait être le rappel d'une demande de bd, il pourrait être le rappel de un http repos demande que vous avez fait. Nœud cherche à maximiser l'efficacité de l'UC en éliminant fil des changements de contexte. Parce que le nœud fait de cette opiniâtre de choix pour TOUS les I/O est asynchrone, ce qui signifie également que tous les cadres/add-ons étayer ce choix. Il est plus facile d'écrire des applications qui sont 100% asynchrone dans le nœud (car nœud vous oblige à écrire des applications qui sont asynchrones).

Encore une fois, je n'ai pas de chiffres pour le prouver d'une façon ou d'une autre, mais je pense que le nœud va remporter la CHARGE de la concurrence pour l'application web standard. Un très optimisé (100% asynchrone) .NET application peut donner l'équivalent node.js app une course pour son argent, mais si vous avez pris une moyenne de toutes les .NET et tous le nœud applications, en moyenne nœud probablement poignées de CHARGE en plus.

Espérons que cela aide.

50voto

Shankar Points 694

J'ai fait un rudimentaire test de performance entre nodejs et IIS. IIS est environ 2,5 fois plus rapide que nodejs lors de débourser le prix "hello, world!". le code ci-dessous.

mon matériel: Dell Latitude E6510, Core i5 (dual core), 8 GO de RAM, Windows 7 Entreprise 64 bits de l'OS

nœud de serveur

runs at http://localhost:9090/
/// <reference path="node-vsdoc.js" />
var http = require("http");
http.createServer(function (request, response) {
response.writeHead(200, { "Content-Type": "text/html" });
response.write("<p>hello, world!</p>");
response.end();
}).listen(9090);

default.htm

hosted by iis at http://localhost/test/
<p>hello, world!</p>

mon propre programme de test à l'aide de task parallel library:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;

namespace HttpBench
{
class Program
{
    private int TotalCount = 100000;
    private int ConcurrentThreads = 1000;
    private int failedCount;
    private int totalBytes;
    private int totalTime;
    private int completedCount;
    private static object lockObj = new object();

    /// <summary>
    /// main entry point
    /// </summary>
    static void Main(string[] args)
    {
        Program p = new Program();
        p.Run(args);
    }

    /// <summary>
    /// actual execution
    /// </summary>
    private void Run(string[] args)
    {
        // check command line
        if (args.Length == 0)
        {
            this.PrintUsage();
            return;
        }
        if (args[0] == "/?" || args[0] == "/h")
        {
            this.PrintUsage();
            return;
        }

        // use parallel library, download data
        ParallelOptions options = new ParallelOptions();
        options.MaxDegreeOfParallelism = this.ConcurrentThreads;
        int start = Environment.TickCount;
        Parallel.For(0, this.TotalCount, options, i =>
            {
                this.DownloadUrl(i, args[0]);
            }
        );
        int end = Environment.TickCount;

        // print results
        this.Print("Total requests sent: {0}", true, this.TotalCount);
        this.Print("Concurrent threads: {0}", true, this.ConcurrentThreads);
        this.Print("Total completed requests: {0}", true, this.completedCount);
        this.Print("Failed requests: {0}", true, this.failedCount);
        this.Print("Sum total of thread times (seconds): {0}", true, this.totalTime / 1000);
        this.Print("Total time taken by this program (seconds): {0}", true, (end - start) / 1000);
        this.Print("Total bytes: {0}", true, this.totalBytes);
    }

    /// <summary>
    /// download data from the given url
    /// </summary>
    private void DownloadUrl(int index, string url)
    {
        using (WebClient client = new WebClient())
        {
            try
            {
                int start = Environment.TickCount;
                byte[] data = client.DownloadData(url);
                int end = Environment.TickCount;
                lock (lockObj)
                {
                    this.totalTime = this.totalTime + (end - start);
                    if (data != null)
                    {
                        this.totalBytes = this.totalBytes + data.Length;
                    }
                }
            }
            catch
            {
                lock (lockObj) { this.failedCount++; }
            }
            lock (lockObj)
            {
                this.completedCount++;
                if (this.completedCount % 10000 == 0)
                {
                    this.Print("Completed {0} requests.", true, this.completedCount);
                }
            }
        }
    }

    /// <summary>
    /// print usage of this program
    /// </summary>
    private void PrintUsage()
    {
        this.Print("usage: httpbench [options] <url>");
    }

    /// <summary>
    /// print exception message to console
    /// </summary>
    private void PrintError(string msg, Exception ex = null, params object[] args)
    {
        StringBuilder sb = new System.Text.StringBuilder();
        sb.Append("Error: ");
        sb.AppendFormat(msg, args);
        if (ex != null)
        {
            sb.Append("Exception: ");
            sb.Append(ex.Message);
        }
        this.Print(sb.ToString());
    }

    /// <summary>
    /// print to console
    /// </summary>
    private void Print(string msg, bool isLine = true, params object[] args)
    {
        if (isLine)
        {
            Console.WriteLine(msg, args);
        }
        else
        {
            Console.Write(msg, args);
        }
    }

}
}

et les résultats:

IIS: httpbench.exe http://localhost/test

Completed 10000 requests.
Completed 20000 requests.
Completed 30000 requests.
Completed 40000 requests.
Completed 50000 requests.
Completed 60000 requests.
Completed 70000 requests.
Completed 80000 requests.
Completed 90000 requests.
Completed 100000 requests.
Total requests sent: 100000
Concurrent threads: 1000
Total completed requests: 100000
Failed requests: 0
Sum total of thread times (seconds): 97
Total time taken by this program (seconds): 16
Total bytes: 2000000

nodejs: httpbench.exe http://localhost:9090/

Completed 10000 requests.
Completed 20000 requests.
Completed 30000 requests.
Completed 40000 requests.
Completed 50000 requests.
Completed 60000 requests.
Completed 70000 requests.
Completed 80000 requests.
Completed 90000 requests.
Completed 100000 requests.
Total requests sent: 100000
Concurrent threads: 1000
Total completed requests: 100000
Failed requests: 0
Sum total of thread times (seconds): 234
Total time taken by this program (seconds): 27
Total bytes: 2000000

conclusion: IIS est plus rapide que nodejs par environ 2,5 fois (sur Windows). C'est un très rudimentaire de test, et ce ne sont pas concluantes. Mais je crois que c'est un bon point de départ. Nodejs est probablement plus rapide sur d'autres serveurs web, sur d'autres plates-formes, mais sur Windows IIS est le gagnant. Les développeurs qui cherchent à convertir leurs ASP.NET MVC pour nodejs doit se mettre en pause et de réfléchir à deux fois avant de continuer.

Mis à jour (5/17/2012) Tomcat (sur windows) semble battre IIS mains vers le bas, environ 3 fois plus rapide que les services internet (IIS) distribue html statique.

tomcat

index.html at http://localhost:8080/test/
<p>hello, world!</p>

tomcat résultats

httpbench.exe http://localhost:8080/test/
Completed 10000 requests.
Completed 20000 requests.
Completed 30000 requests.
Completed 40000 requests.
Completed 50000 requests.
Completed 60000 requests.
Completed 70000 requests.
Completed 80000 requests.
Completed 90000 requests.
Completed 100000 requests.
Total requests sent: 100000
Concurrent threads: 1000
Total completed requests: 100000
Failed requests: 0
Sum total of thread times (seconds): 31
Total time taken by this program (seconds): 5
Total bytes: 2000000

mise à jour de la conclusion: j'ai exécuté le programme de test plusieurs fois. Tomcat semble être la manière la plus rapide serveur distribue HTML STATIQUE, SUR WINDOWS.

Mis à jour (5/18/2012) Auparavant, j'avais de 100 000 total des demandes de 10 000 demandes simultanées. J'ai augmenté à 1 000 000 total requess et 100 000 demandes simultanées. IIS sort comme crier gagnant, avec Nodejs carénage le pire. J'ai tabularized les résultats ci-dessous:

NodeJS vs IIS vs Tomcat serving STATIC HTML on WINDOWS.

34voto

ttekin Points 91

NIO serveurs (nodejs, etc) ont tendance à être plus rapide que la BIO serveurs. (IIS, etc). De retour à ma réclamation,

Techempower est une société spécialisée sur le framework web de repères. Ils sont très ouverts et ont un niveau moyen de tester tous les framewrks. De vérifier la http://www.techempower.com/benchmarks/

Ronde 9 tests est actuellement la dernière. Il y a beaucoup de IIS saveurs testé, mais aspnet-dépouillé semble être la manière la plus rapide IIS variante. Voici les résultats: La Sérialisation Json: NodeJS: 228,887, aspnet-dépouillé: 105,272 Seule Requête: nodejs-mysql: 88,597, aspnet-dépouillé-raw: 47,066 Plusieurs Requêtes: nodejs-mysql: 8,878, aspnet-dépouillé-raw: 3,915 Texte brut: nodejs: 289,578, aspnet-dépouillé: 109,136

Dans tous les cas, NodeJS a tendance à être 2 fois+ rapide que IIS.

16voto

Number 9 Points 305

Je suis d’accord avec Marcus Granstrom, que le scénario est très important ici.

Pour être honnête, on dirait que vous faites une décision architecturale élevée aux chocs. Mon Conseil serait d’isoler les sujets de préoccupation et faire un « bake off » entre quelque piles que vous envisagez.

À la fin de la journée, vous êtes responsable de la décision et je ne pense pas que l’excuse « un mec sur Stackoverflow m’a montré un article qui dit que ce serait bien » il coupera avec votre patron.

0voto

Ondrej Rozinek Points 47

Principale différence de ce que je vois, c’est ce nœud .js est dynamic programming language (vérification du type), donc les types doivent être en cours d’exécution dérivé. Les langages fortement typés comme c# .NET a théoriquement beaucoup plus potentiels remporte la lutte contre le nœud .js (et PHP etc.), particulièrement où est calcul cher. Par la façon dont le .NET devrait avoir meilleure interopérabilité native avec C/C++ que noeud .js.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X