mirror of
https://github.com/nodejs/node-v0.x-archive.git
synced 2026-04-28 03:01:10 -04:00
Compare commits
104 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc103ae020 | ||
|
|
fea3919d1b | ||
|
|
b5dc54c6ed | ||
|
|
2fb393a768 | ||
|
|
80974dc85b | ||
|
|
16f736200a | ||
|
|
d29e62d564 | ||
|
|
41eca918e5 | ||
|
|
45a01aff59 | ||
|
|
55aa7b17ab | ||
|
|
1165878e3c | ||
|
|
b98958d7fe | ||
|
|
448cbaf395 | ||
|
|
b8eee9c6f0 | ||
|
|
936a038bb7 | ||
|
|
529cdad2dd | ||
|
|
7140933fcc | ||
|
|
27f6a20fdb | ||
|
|
a30daa7b6c | ||
|
|
01035714a5 | ||
|
|
f6f739b3a2 | ||
|
|
d7c1690c74 | ||
|
|
7bf46bc980 | ||
|
|
bcbc52e257 | ||
|
|
c00a6a7169 | ||
|
|
1d8b154e14 | ||
|
|
84f4ce742f | ||
|
|
f9cc35fa57 | ||
|
|
d506a42765 | ||
|
|
09a41a7f9c | ||
|
|
8dcd6dccab | ||
|
|
1375b8ed39 | ||
|
|
a3333e7393 | ||
|
|
d965640662 | ||
|
|
ee253b374d | ||
|
|
b17b28531b | ||
|
|
10af67714b | ||
|
|
180a04805b | ||
|
|
ee21920571 | ||
|
|
66bce65d33 | ||
|
|
2005ef9e37 | ||
|
|
3816ebc85f | ||
|
|
4c5520a37e | ||
|
|
0ddad3fbc7 | ||
|
|
db6a1788b2 | ||
|
|
1d17874a7d | ||
|
|
3191802605 | ||
|
|
da235fa12c | ||
|
|
92fb664bfc | ||
|
|
7704fb9711 | ||
|
|
c099e274d2 | ||
|
|
c86f3c5d5c | ||
|
|
9b8577230f | ||
|
|
9f6f26028f | ||
|
|
44f8756aab | ||
|
|
ae2f566fec | ||
|
|
2f071ac7d1 | ||
|
|
bd8ea2bb85 | ||
|
|
35682ac88e | ||
|
|
5bbebf3593 | ||
|
|
0b9dab650e | ||
|
|
a6659e7612 | ||
|
|
727843eea1 | ||
|
|
7e9a0173d7 | ||
|
|
74b70c3cb1 | ||
|
|
d5deb4c4a3 | ||
|
|
cc0164bc12 | ||
|
|
ccd1304c5b | ||
|
|
3d3d00d524 | ||
|
|
dffa9e76a1 | ||
|
|
90374797f0 | ||
|
|
c1a4e10156 | ||
|
|
b655ce5c08 | ||
|
|
b30b60717d | ||
|
|
b2dfea0361 | ||
|
|
610743daee | ||
|
|
df891c36a4 | ||
|
|
f35a8298b1 | ||
|
|
294c455678 | ||
|
|
14f16ec592 | ||
|
|
cdee88051d | ||
|
|
b39b15d53f | ||
|
|
b895568800 | ||
|
|
ead58b9a93 | ||
|
|
c306fa241c | ||
|
|
22f67f8585 | ||
|
|
416aa73946 | ||
|
|
6a39a7ed83 | ||
|
|
ad960f4462 | ||
|
|
f78691e45c | ||
|
|
3d8137c582 | ||
|
|
c14c445cb6 | ||
|
|
b9ca8435f5 | ||
|
|
baa24bd40e | ||
|
|
7a836ef813 | ||
|
|
a2b9e02d83 | ||
|
|
3f7c791b13 | ||
|
|
53dac7c341 | ||
|
|
c43ddf7acd | ||
|
|
699fdfaa43 | ||
|
|
8d2e79451e | ||
|
|
760efc0758 | ||
|
|
1b1ad1d363 | ||
|
|
c3eafdd3a4 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1 +0,0 @@
|
||||
test/fixtures/* -text
|
||||
73
.gitignore
vendored
73
.gitignore
vendored
@@ -1,76 +1,15 @@
|
||||
core
|
||||
vgcore.*
|
||||
v8*.log
|
||||
perf.data
|
||||
perf.data.old
|
||||
build
|
||||
.waf*
|
||||
tags
|
||||
.lock-wscript
|
||||
*.pyc
|
||||
*.patch
|
||||
doc/api.xml
|
||||
doc/api.html
|
||||
doc/changelog.html
|
||||
doc/node.1
|
||||
test/fixtures/hello.txt
|
||||
tmp/
|
||||
node
|
||||
node_g
|
||||
*.swp
|
||||
.benchmark_reports
|
||||
/.project
|
||||
/.cproject
|
||||
icu_config.gypi
|
||||
|
||||
/out
|
||||
|
||||
# various stuff that VC++ produces/uses
|
||||
Debug/
|
||||
Release/
|
||||
!doc/blog/**
|
||||
*.sln
|
||||
!nodemsi.sln
|
||||
*.suo
|
||||
*.vcproj
|
||||
*.vcxproj
|
||||
!custom_actions.vcxproj
|
||||
*.vcxproj.user
|
||||
*.vcxproj.filters
|
||||
UpgradeLog*.XML
|
||||
_UpgradeReport_Files/
|
||||
ipch/
|
||||
*.sdf
|
||||
*.opensdf
|
||||
|
||||
/config.mk
|
||||
/config.gypi
|
||||
*-nodegyp*
|
||||
/gyp-mac-tool
|
||||
/dist-osx
|
||||
/npm.wxs
|
||||
/tools/msvs/npm.wixobj
|
||||
/test/addons/doc-*/
|
||||
email.md
|
||||
deps/v8-*
|
||||
deps/icu
|
||||
deps/icu*.zip
|
||||
deps/icu*.tgz
|
||||
deps/icu-tmp
|
||||
./node_modules
|
||||
.svn/
|
||||
|
||||
# generated by gyp on Windows
|
||||
deps/openssl/openssl.props
|
||||
deps/openssl/openssl.targets
|
||||
deps/openssl/openssl.xml
|
||||
|
||||
# generated by gyp on android
|
||||
/*.target.mk
|
||||
/*.host.mk
|
||||
deps/openssl/openssl.target.mk
|
||||
deps/zlib/zlib.target.mk
|
||||
|
||||
# build/release artifacts
|
||||
/*.tar.gz
|
||||
/SHASUMS*.txt*
|
||||
|
||||
/tools/wrk/wrk
|
||||
|
||||
# test artifacts
|
||||
tools/faketime
|
||||
icu_config.gypi
|
||||
|
||||
134
.mailmap
134
.mailmap
@@ -1,134 +0,0 @@
|
||||
Aaron Heckmann <aaron.heckmann@gmail.com> <aaron.heckmann+github@gmail.com>
|
||||
Abe Fettig <abefettig@gmail.com> <abe@fettig.net>
|
||||
Alex Kocharin <rlidwka@kocharin.ru>
|
||||
Alex Kocharin <rlidwka@kocharin.ru> <alex@kocharin.ru>
|
||||
Alexey Kupershtokh <wicked@alawar.com>
|
||||
Alexis Campailla <orangemocha@github.com>
|
||||
Alexis Sellier <self@cloudhead.net>
|
||||
Alexis Sellier <self@cloudhead.net> <alexis@cloudhead.io>
|
||||
Arlo Breault <arlolra@gmail.com>
|
||||
Artem Zaytsev <a.arepo@gmail.com>
|
||||
Atsuo Fukaya <fukayatsu@gmail.com>
|
||||
Ben Noordhuis <info@bnoordhuis.nl> <bnoordhuis@bender.(none)>
|
||||
Ben Taber <ben.taber@gmail.com>
|
||||
Bert Belder <bertbelder@gmail.com> <bert@piscisaureus2.(none)>
|
||||
Bert Belder <bertbelder@gmail.com> <info@2bs.nl>
|
||||
Bert Belder <bertbelder@gmail.com> <piscisaureus@Berts-MacBook-Pro.local>
|
||||
Brandon Benvie <brandon@bbenvie.com> <brandon@brandonbenvie.com>
|
||||
Brandon Cheng <bcheng.gt@gmail.com>
|
||||
Brian White <mscdex@mscdex.net>
|
||||
Brian White <mscdex@mscdex.net> <mscdex@gmail.com>
|
||||
Chew Choon Keat <choonkeat@gmail.com>
|
||||
Christopher Lenz <cmlenz@gmail.com> <chris@lamech.local>
|
||||
Colin Ihrig <cjihrig@gmail.com>
|
||||
Daniel Berger <code+node@dpbis.net>
|
||||
Daniel Chcouri <333222@gmail.com>
|
||||
Daniel Gröber <darklord@darkboxed.org>
|
||||
Daniel Gröber <darklord@darkboxed.org> <dxld@darkboxed.org>
|
||||
Daniel Pihlström <sciolist.se@gmail.com>
|
||||
Dave Pacheco <dap@joyent.com> <dap@cs.brown.edu>
|
||||
David Siegel <david@artcom.de> <david.siegel@artcom.de>
|
||||
Domenic Denicola <domenic@domenicdenicola.com>
|
||||
Doron Pagot <doronpagot@gmail.com>
|
||||
Eduard Burtescu <eddy_me08@yahoo.com>
|
||||
Einar Otto Stangvik <einaros@gmail.com>
|
||||
Elliott Cable <me@ell.io>
|
||||
EungJun Yi <semtlenori@gmail.com>
|
||||
Evan Larkin <evan.larkin.il.com> <evan.larkin.iit@gmail.com>
|
||||
Farid Neshat <FaridN_SOAD@yahoo.com>
|
||||
Felix Böhm <felixboehm55@googlemail.com> <me@feedic.com>
|
||||
Felix Geisendörfer <felix@debuggable.com>
|
||||
Felix Geisendörfer <felix@debuggable.com>
|
||||
Friedemann Altrock <frodenius@gmail.com>
|
||||
Fuji Goro <gfuji@cpan.org>
|
||||
Gabriel de Perthuis <g2p.code@gmail.com>
|
||||
Gil Pedersen <git@gpost.dk> <github@gpost.dk>
|
||||
Guillaume Goussard <guillaume.goussard@mgo.com>
|
||||
Henry Chin <hheennrryy@gmail.com>
|
||||
Herbert Vojčík <herby@mailbox.sk>
|
||||
Igor Soarez <igorsoarez@gmail.com>
|
||||
Igor Zinkovsky <igorzi@microsoft.com>
|
||||
Isaac Z. Schlueter <i@izs.me>
|
||||
Isaac Z. Schlueter <i@izs.me> <i@foohack.com>
|
||||
Jake Verbaten <raynos2@gmail.com>
|
||||
Jered Schmidt <tr@nslator.jp>
|
||||
Jochen Eisinger <jochen@chromium.org>
|
||||
Joe Shaw <joe@joeshaw.org> <joeshaw@litl.com>
|
||||
Johan Bergström <bugs@bergstroem.nu>
|
||||
Johan Dahlberg <jfd@distrop.com> <dahlberg.johan@gmail.com>
|
||||
Jonas Pfenniger <jonas@pfenniger.name> <jonas@stvs.ch>
|
||||
Jonathan Rentzsch <jwr.git@redshed.net>
|
||||
Josh Erickson <josh@snoj.us>
|
||||
Joshua S. Weinstein <josher19@users.sf.net>
|
||||
Jérémy Lal <kapouer@melix.org>
|
||||
Jérémy Lal <kapouer@melix.org> <holisme@gmail.com>
|
||||
Kai Sasaki Lewuathe <sasaki_kai@lewuathe.sakura.ne.jp>
|
||||
Kazuyuki Yamada <tasogare.pg@gmail.com>
|
||||
Koichi Kobayashi <koichik@improvement.jp>
|
||||
Kris Kowal <kris.kowal@cixar.com>
|
||||
Kyle Robinson Young <kyle@dontkry.com>
|
||||
Luke Bayes <lbayes@patternpark.com>
|
||||
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
|
||||
Mathias Pettersson <mape@mape.me>
|
||||
Michael Bernstein <michaelrbernstein@gmail.com>
|
||||
Michael Wilber <gcr@sneakygcr.net>
|
||||
Micheil Smith <micheil@brandedcode.com> <micheil@yettobebranded.net>
|
||||
Mikael Bourges-Sevenier <mikeseven@gmail.com> <msevenier@motorola.com>
|
||||
Nebu Pookins<nebu@nebupookins.net>
|
||||
Nicholas Kinsey <pyrotechnick@feistystudios.com>
|
||||
Nicholas Vavilov <vvnicholas@gmail.com>
|
||||
Onne Gorter <onne@onnlucky.com>
|
||||
Paul Querna <pquerna@apache.org> <paul@querna.org>
|
||||
Ray Morgan <rmorgan@zappos.com>
|
||||
Ray Solomon <raybsolomon@gmail.com>
|
||||
Rick Olson <technoweenie@gmail.com>
|
||||
Ryan Dahl <ry@tinyclouds.org>
|
||||
Ryan Emery <seebees@gmail.com>
|
||||
Sam Shull <brickysam26@gmail.com> <brickysam26@samuel-shulls-computer.local>
|
||||
Sam Shull <brickysam26@gmail.com> <sshull@squaremouth.com>
|
||||
Sambasiva Suda <sambasivarao@gmail.com>
|
||||
San-Tai Hsu <v@fatpipi.com>
|
||||
Scott Blomquist <github@scott.blomqui.st> <sblom@microsoft.com>
|
||||
Sergey Kryzhanovsky <skryzhanovsky@gmail.com> <another@dhcp199-223-red.yandex.net>
|
||||
Shannen Saez <shannenlaptop@gmail.com>
|
||||
Shigeki Ohtsu <ohtsu@d.jp> <ohtsu@iij.ad.jp>
|
||||
Siddharth Mahendraker <siddharth_mahen@hotmail.com> <siddharth_mahen@me.com>
|
||||
Simon Willison <simon@simonwillison.net>
|
||||
Stanislav Opichal <opichals@gmail.com>
|
||||
Stefan Bühler <stbuehler@web.de>
|
||||
TJ Holowaychuk <tj@vision-media.ca>
|
||||
TJ Holowaychuk <tj@vision-media.ca> <tjholowayhuk@gmail.com>
|
||||
Tadashi SAWADA <cesare@mayverse.jp>
|
||||
Takahiro ANDO <takahiro.ando@gmail.com>
|
||||
Ted Young <ted@radicaldesigns.org>
|
||||
Thomas Lee <thomas.lee@shinetech.com> <tom@tom-debian.sensis.com.au>
|
||||
Tim Caswell <tim@creationix.com> <tim@0-26-8-e9-4c-e1.dyn.utdallas.edu>
|
||||
Tim Price <timprice@mangoraft.com>
|
||||
Tim Smart <timehandgod@gmail.com> <tim@fostle.com>
|
||||
Tim Smart <timehandgod@gmail.com> <timehandgod@gmail.com>
|
||||
Tom Hughes-Croucher <tom.hughes@palm.com>
|
||||
Tom Hughes-Croucher <tom.hughes@palm.com> <tom_croucher@yahoo.com>
|
||||
Trevor Burnham <trevor@databraid.com> <trevorburnham@gmail.com>
|
||||
Tyler Larson <talltyler@gmail.com>
|
||||
Vincent Voyer <v@fasterize.com>
|
||||
Willi Eggeling <email@wje-online.de>
|
||||
Yiyu He <dead_horse@qq.com>
|
||||
Yoshihiro KIKUCHI <yknetg@gmail.com>
|
||||
Yuichiro MASUI <masui@masuidrive.jp>
|
||||
Yunsong Guo <eilian.yunsong@gmail.com>
|
||||
Zachary Scott <zachary@zacharyscott.net> <zachary.s.scott@gmail.com>
|
||||
Zoran Tomicic <ztomicic@gmail.com>
|
||||
|
||||
# These people didn't contribute patches to node directly,
|
||||
# but we've landed their v8 patches in the node repository:
|
||||
Daniel Clifford <danno@chromium.org>
|
||||
Erik Corry <erik.corry@gmail.com>
|
||||
Jakob Kummerow <jkummerow@chromium.org>
|
||||
Kevin Millikin <kmillikin@chromium.org>
|
||||
Lasse R.H. Nielsen <lrn@chromium.org>
|
||||
Michael Starzinger <mstarzinger@chromium.org>
|
||||
Toon Verwaest <verwaest@chromium.org>
|
||||
Vyacheslav Egorov <vegorov@chromium.org>
|
||||
Yang Guo <yangguo@chromium.org>
|
||||
Dan Carney <dcarney@chromium.org>
|
||||
Sven Panne <svenpanne@chromium.org>
|
||||
806
AUTHORS
806
AUTHORS
@@ -1,681 +1,125 @@
|
||||
AJ ONeal
|
||||
Aaditya Bhatia
|
||||
Aapo Laitinen
|
||||
Aaron Cannon
|
||||
Aaron Heckmann
|
||||
Aaron Jacobs
|
||||
Abe Fettig
|
||||
Abimanyu Raja
|
||||
Adam Blackburn
|
||||
Adam Lippai
|
||||
Adam Luikart
|
||||
Adam Malcontenti-Wilson
|
||||
Adam Wiggins
|
||||
Adrian Lang
|
||||
Ahamed Nafeez
|
||||
Aku Kotkavuo
|
||||
Alejandro Oviedo
|
||||
Alex Kocharin
|
||||
Alex Xu
|
||||
AlexKVal
|
||||
Alexander Uvarov
|
||||
Alexandr Emelin
|
||||
Alexandre Marangone
|
||||
Alexey Kupershtokh
|
||||
Alexis Campailla
|
||||
Alexis Sellier
|
||||
Ali Farhadi
|
||||
Amir Saboury
|
||||
Anders Conbere
|
||||
Andreas Madsen
|
||||
Andreas Reich
|
||||
Andrei Sedoi
|
||||
Andrew Chilton
|
||||
Andrew Hart
|
||||
Andrew Johnston
|
||||
Andrew Low
|
||||
Andrew Naylor
|
||||
Andrew Oppenlander
|
||||
Andrew Paprocki
|
||||
Andrew Teich
|
||||
Andrius Bentkus
|
||||
Andy Burke
|
||||
Ankur Oberoi
|
||||
Anthony Pesch
|
||||
Anton Khlynovskiy
|
||||
Antony Bailey
|
||||
Antranig Basman
|
||||
Aria Stewart
|
||||
Arianit Uka
|
||||
Arlo Breault
|
||||
Arnout Kazemier
|
||||
Artem Zaytsev
|
||||
Artur Adib
|
||||
Artur Cistov
|
||||
Ashok Mudukutore
|
||||
Atsuo Fukaya
|
||||
Atsuya Takagi
|
||||
Austin Moran
|
||||
Avi Flax
|
||||
Bearice Ren
|
||||
Ben Burns
|
||||
Ben Kelly
|
||||
Ben Leslie
|
||||
Ben Lowery
|
||||
Ben Noordhuis
|
||||
Ben Taber
|
||||
Ben Weaver
|
||||
Ben Williamson
|
||||
Benjamin Fritsch
|
||||
Benjamin Kramer
|
||||
Benjamin Pasero
|
||||
Benjamin Ruston
|
||||
Benjamin Thomas
|
||||
Benjamin Waters
|
||||
Benoit Vallée
|
||||
Bert Belder
|
||||
Blaine Cook
|
||||
Blake Miner
|
||||
Blake Mizerany
|
||||
Bradley Meck
|
||||
Brandon Beacher
|
||||
Brandon Benvie
|
||||
Brandon Cheng
|
||||
Brandon Frohs
|
||||
Brandon Philips
|
||||
Brandon Wilson
|
||||
Brendan Ashworth
|
||||
Brett Kiefer
|
||||
Brian Hammond
|
||||
Brian McKenna
|
||||
Brian Schroeder
|
||||
Brian White
|
||||
Bruno Jouhier
|
||||
Bryan Cantrill
|
||||
C. Scott Ananian
|
||||
CGavrila
|
||||
Calvin Metcalf
|
||||
Cam Pedersen
|
||||
Cam Swords
|
||||
Carlos Campderrós
|
||||
Carson McDonald
|
||||
Carter Allen
|
||||
Chad Johnston
|
||||
Chad Rhyner
|
||||
Chandra Sekar S
|
||||
Charles
|
||||
Charles Lehner
|
||||
Charlie McConnell
|
||||
Cheng Zhao
|
||||
Chew Choon Keat
|
||||
Chris Barber
|
||||
Chris Dent
|
||||
Chris Dickinson
|
||||
ChrisWren
|
||||
Christian
|
||||
Christian Ress
|
||||
Christian Tellnes
|
||||
Christopher Jeffrey
|
||||
Christopher Lenz
|
||||
Christopher Wright
|
||||
Colin Ihrig
|
||||
Colton Baker
|
||||
Connor Dunn
|
||||
Damon Oehlman
|
||||
Dan Carney
|
||||
Dan Dascalescu
|
||||
Dan Kaplun
|
||||
Dan Kohn
|
||||
Dan Milon
|
||||
Dan Søndergaard
|
||||
Dan VerWeire
|
||||
Dan Williams
|
||||
Dane Springmeyer
|
||||
Daniel Berger
|
||||
Daniel Chatfield
|
||||
Daniel Chcouri
|
||||
Daniel Clifford
|
||||
Daniel Ennis
|
||||
Daniel G. Taylor
|
||||
Daniel Gröber
|
||||
Daniel Moore
|
||||
Daniel Pihlström
|
||||
Danny Coates
|
||||
Dav Glass
|
||||
Dave Irvine
|
||||
Dave Olszewski
|
||||
Dave Pacheco
|
||||
David Björklund
|
||||
David Braun
|
||||
David Chan
|
||||
David Siegel
|
||||
David Sklar
|
||||
David Trejo
|
||||
Dean McNamee
|
||||
Debjeet Biswas
|
||||
Denys Zariaiev
|
||||
Devin Torres
|
||||
Devon Govett
|
||||
Dmitri Melikyan
|
||||
Dmitriy Shalashov
|
||||
Dmitry Baranovskiy
|
||||
Dmitry Nizovtsev
|
||||
Domenic Denicola
|
||||
Dominic Tarr
|
||||
Doron Pagot
|
||||
Duan Yao
|
||||
E. Azer Koçulu
|
||||
Ed Morley
|
||||
Ed Umansky
|
||||
Eduard Burtescu
|
||||
Edward Hutchins
|
||||
Einar Otto Stangvik
|
||||
Eivind Uggedal
|
||||
Eli Skeggs
|
||||
Elijah Insua
|
||||
Elliott Cable
|
||||
Emerson Macedo
|
||||
Emmanuel Odeke
|
||||
Eran Hammer
|
||||
Eric Lovett
|
||||
Eric Mill
|
||||
Eric Schrock
|
||||
Erik Corry
|
||||
Erik Dubbelboer
|
||||
Erik Lundin
|
||||
Erwin van der Koogh
|
||||
Euan
|
||||
Eugen Dueck
|
||||
Eugene Girshov
|
||||
EungJun Yi
|
||||
Evan Carroll
|
||||
Evan Larkin
|
||||
Evan Lucas
|
||||
Evan Martin
|
||||
Evan Oxfeld
|
||||
Evan Rutledge Borden
|
||||
Evan Solomon
|
||||
Ezequiel Rabinovich
|
||||
Farid Neshat
|
||||
Farrin Reid
|
||||
Fedor Indutny
|
||||
Felix Böhm
|
||||
Felix Geisendörfer
|
||||
Feross Aboukhadijeh
|
||||
Florin-Cristian Gavrila
|
||||
Forrest L Norvell
|
||||
Francois Marier
|
||||
Frank Cash
|
||||
Fred K. Schott
|
||||
Frederico Silva
|
||||
Friedemann Altrock
|
||||
Frédéric Germain
|
||||
Fuji Goro
|
||||
Gabriel Falkenberg
|
||||
Gabriel Farrell
|
||||
Gabriel Wicke
|
||||
Gabriel de Perthuis
|
||||
Garen Torikian
|
||||
Geir Hauge
|
||||
George Miroshnykov
|
||||
George Shank
|
||||
George Stagas
|
||||
Gil Pedersen
|
||||
Gireesh Punathil
|
||||
Girish Ramakrishnan
|
||||
Glen Low
|
||||
Glen Mailer
|
||||
Goh Yisheng (Andrew)
|
||||
Golo Roden
|
||||
Greg Brail
|
||||
Greg Hughes
|
||||
Greg Sabia Tucker
|
||||
Guglielmo Ferri
|
||||
Guilherme de Souza
|
||||
Guillaume Goussard
|
||||
Guillaume Tuton
|
||||
Guillermo Rauch
|
||||
Henry Chin
|
||||
Henry Rawas
|
||||
Herbert Vojčík
|
||||
Herman Lee
|
||||
Håvard Stranden
|
||||
Ian Babrou
|
||||
Igor Soarez
|
||||
Igor Zinkovsky
|
||||
Illarionov Oleg
|
||||
Ilya Dmitrichenko
|
||||
Ingmar Runge
|
||||
Ionică Bizău
|
||||
Isaac Burns
|
||||
Isaac Z. Schlueter
|
||||
Iskren Ivov Chernev
|
||||
Ivan Torres
|
||||
J. Lee Coltrane
|
||||
Jacek Becela
|
||||
Jackson Tian
|
||||
Jacob Gable
|
||||
Jacob Groundwater
|
||||
Jacob H.C. Kragh
|
||||
Jacob Hoffman-Andrews
|
||||
Jake Verbaten
|
||||
Jakob Gillich
|
||||
Jakob Kummerow
|
||||
Jakub Lekstan
|
||||
James Campos
|
||||
James Duncan
|
||||
James Ferguson
|
||||
James Halliday
|
||||
James Hartig
|
||||
James Herdman
|
||||
James Hight
|
||||
James Koval
|
||||
James M Snell
|
||||
James Pickard
|
||||
Jan Kassens
|
||||
Jan Krems
|
||||
Jan Lehnardt
|
||||
Jan Schär
|
||||
Jan Wynholds
|
||||
Jann Horn
|
||||
Jason Gerfen
|
||||
Javier Hernández
|
||||
Jay Beavers
|
||||
Jeff Barczewski
|
||||
Jeff Smick
|
||||
Jeff Switzer
|
||||
JeongHoon Byun
|
||||
Jered Schmidt
|
||||
Jeremy Ashkenas
|
||||
Jeremy Martin
|
||||
Jeremy Selier
|
||||
Jeroen Janssen
|
||||
Jerome Etienne
|
||||
Jesús Leganés Combarro "piranna
|
||||
Jicheng Li
|
||||
Jim Schubert
|
||||
Jimb Esser
|
||||
Jo Liss
|
||||
Jochen Eisinger
|
||||
Joe Andaverde
|
||||
Joe Shaw
|
||||
Joe Walnes
|
||||
Joel Brandt
|
||||
Johan Bergström
|
||||
Johan Dahlberg
|
||||
Johan Euphrosine
|
||||
Johan Sørensen
|
||||
Johannes Ewald
|
||||
Johannes Wüller
|
||||
John Albietz
|
||||
Johnny Ray
|
||||
Jon Crosby
|
||||
Jonas Dohse
|
||||
Jonas Pfenniger
|
||||
Jonas Westerlund
|
||||
Jonathan Johnson
|
||||
Jonathan Knezek
|
||||
Jonathan Reem
|
||||
Jonathan Rentzsch
|
||||
Jordan Sissel
|
||||
Jorge Chamorro Bieling
|
||||
Joseph Pecoraro
|
||||
Josh Dague
|
||||
Josh Erickson
|
||||
Joshaven Potter
|
||||
Joshua Holbrook
|
||||
Joshua Peek
|
||||
Joshua S. Weinstein
|
||||
João Reis
|
||||
Ju-yeong Park
|
||||
Juanjo
|
||||
Julian Gruber
|
||||
Julian Lamb
|
||||
Julien Fontanet
|
||||
Julien Gilli
|
||||
Jun Ma
|
||||
Justin Plock
|
||||
Jérémy Lal
|
||||
Jörn Horstmann
|
||||
Kai Chen
|
||||
Kai Groner
|
||||
Kai Sasaki Lewuathe
|
||||
Kang-Hao Kenny
|
||||
Karl Guertin
|
||||
Karl Skomski
|
||||
Kat Marchán
|
||||
Kazuyuki Yamada
|
||||
Keith M Wesolowski
|
||||
Kelly Gerber
|
||||
Kenan Sulayman
|
||||
Kevin Bowman
|
||||
Kevin Decker
|
||||
Kevin Gadd
|
||||
Kevin Locke
|
||||
Kevin Millikin
|
||||
Kevin Simper
|
||||
Kevin van Zonneveld
|
||||
Kip Gebhardt
|
||||
Kiyoshi Nomo
|
||||
Koichi Kobayashi
|
||||
Konstantin Käfer
|
||||
Kris Kowal
|
||||
Krishna Rajendran
|
||||
Krzysztof Chrapka
|
||||
Kyle Robinson Young
|
||||
Lalit Kapoor
|
||||
Lars-Magnus Skog
|
||||
Lasse R.H. Nielsen
|
||||
Lev Gimelfarb
|
||||
Linus Mårtensson
|
||||
Linus Unnebäck
|
||||
Logan Smyth
|
||||
Lorenz Leutgeb
|
||||
Lucio M. Tato
|
||||
Luis Reis
|
||||
Luke Arduini
|
||||
Luke Bayes
|
||||
Luke Gallagher
|
||||
MK Safi
|
||||
Maciej Małecki
|
||||
Majid Arif Siddiqui
|
||||
Malte-Thorben Bruns
|
||||
Manav Rathi
|
||||
Marc Harter
|
||||
Marcel Laverdet
|
||||
Marcin Kostrzewa
|
||||
Marco Rogers
|
||||
Mariano Iglesias
|
||||
Mark Cavage
|
||||
Mark Hansen
|
||||
Mark Nottingham
|
||||
Mark Stosberg
|
||||
Marshall Culpepper
|
||||
Mathias Buus
|
||||
Mathias Bynens
|
||||
Mathias Küsel
|
||||
Mathias Pettersson
|
||||
Mathias Schreck
|
||||
Matt Brubeck
|
||||
Matt Ezell
|
||||
Matt Gollob
|
||||
Matt Ranney
|
||||
Matt Robenolt
|
||||
Matthew Aynalem
|
||||
Matthew Fitzsimmons
|
||||
Matthias Bartelmeß
|
||||
Maurice Butler
|
||||
Max Ogden
|
||||
Maxim Bogushevich
|
||||
Maxime Quandalle
|
||||
Maxwell Krohn
|
||||
Michael Axiak
|
||||
Michael Bernstein
|
||||
Michael Carter
|
||||
Michael Dawson
|
||||
Michael Hart
|
||||
Michael Jackson
|
||||
Michael Kebe
|
||||
Michael Ridgway
|
||||
Michael Starzinger
|
||||
Michael Stillwell
|
||||
Michael Thomas
|
||||
Michael Wilber
|
||||
Michaeljohn Clement
|
||||
Micheil Smith
|
||||
Mickael van der Beek
|
||||
Mickaël Delahaye
|
||||
Mihai Călin Bazon
|
||||
Mikael Bourges-Sevenier
|
||||
Mike Harsch
|
||||
Mike Morearty
|
||||
Mike Pennisi
|
||||
Mike Tunnicliffe
|
||||
Mikeal Rogers
|
||||
Ming Liu
|
||||
Miroslav Bajtos
|
||||
Miroslav Bajtoš
|
||||
Mitar
|
||||
Mustansir Golawala
|
||||
Myles Byrne
|
||||
Nao Iizuka
|
||||
Nathan Friedly
|
||||
Nathan Rajlich
|
||||
Nathan Woltman
|
||||
Nathan Zadoks
|
||||
Nebu Pookins
|
||||
Nicholas Kinsey
|
||||
Nicholas Vavilov
|
||||
Nick Apperson
|
||||
Nick Campbell
|
||||
Nick Desaulniers
|
||||
Nick Muerdter
|
||||
Nick Simmons
|
||||
Nick Stenning
|
||||
Nick Sullivan
|
||||
Niclas Hoyer
|
||||
Nicolas Chambrier
|
||||
Nicolas Kaiser
|
||||
Nicolas LaCasse
|
||||
Nicolas Talle
|
||||
Nikhil Marathe
|
||||
Niklas Fiekas
|
||||
Nirk Niggler
|
||||
Nuno Job
|
||||
Oguz Bastemur
|
||||
Ole André Vadla Ravnås
|
||||
Oleg Efimov
|
||||
Oleg Slobodskoi
|
||||
Olivier Lalonde
|
||||
Olof Johansson
|
||||
Onne Gorter
|
||||
Orlando Vazquez
|
||||
Paddy Byers
|
||||
Paolo Fragomeni
|
||||
Patrick Mooney
|
||||
Patrik Stutz
|
||||
Paul Loyd
|
||||
Paul Querna
|
||||
Paul Serby
|
||||
Paul Vorbach
|
||||
Paulo Matias
|
||||
Paulo McNally
|
||||
Pavel Lang
|
||||
Pedro Ballesteros
|
||||
Pedro Teixeira
|
||||
Peter Bright
|
||||
Peter Dekkers
|
||||
Peter Griess
|
||||
Peter Lyons
|
||||
Peter Rust
|
||||
Peter Rybin
|
||||
Peteris Krumins
|
||||
Phil Sung
|
||||
Philip Tellis
|
||||
Philipp Hagemeister
|
||||
Phillip Alexander
|
||||
Pierre-Alexandre St-Jean
|
||||
Pooya Karimian
|
||||
Rafael Garcia
|
||||
Rafael Henrique Moreira
|
||||
Raffaele Sena
|
||||
Rasmus Andersson
|
||||
Rasmus Christian Pedersen
|
||||
Ray Morgan
|
||||
Ray Solomon
|
||||
Raymond Feng
|
||||
Rebecca Turner
|
||||
Refael Ackermann
|
||||
Reid Burke
|
||||
Rhys Jones
|
||||
Richard Rodger
|
||||
Rick Olson
|
||||
Rick Yakubowski
|
||||
Ricky Ng-Adam
|
||||
Rob Ellis
|
||||
Robert Keizer
|
||||
Robert Kowalski
|
||||
Robert Mustacchi
|
||||
Robin Lee
|
||||
Rod Vagg
|
||||
Rohini Harendra
|
||||
Roly Fentanes
|
||||
Roman Klauke
|
||||
Roman Shtylman
|
||||
Ron Korving
|
||||
Rory Bradford
|
||||
Ruben Rodriguez
|
||||
Russ Bradberry
|
||||
Russell Haering
|
||||
Ryan Cole
|
||||
Ryan Dahl
|
||||
Ryan Doenges
|
||||
Ryan Emery
|
||||
Ryan Graham
|
||||
Ryan McGrath
|
||||
Ryan Petrello
|
||||
Ryuichi Okumura
|
||||
Ryunosuke SATO
|
||||
Sadique Ali
|
||||
Sam Hughes
|
||||
Sam Roberts
|
||||
Sam Shull
|
||||
Sam Stephenson
|
||||
Sambasiva Suda
|
||||
Sami Samhuri
|
||||
San-Tai Hsu
|
||||
Saúl Ibarra Corretgé
|
||||
Scott Anderson
|
||||
Scott Blomquist
|
||||
Scott González
|
||||
Scott McWhirter
|
||||
Scott Taylor
|
||||
Sean Braithwaite
|
||||
Sean Coates
|
||||
Sean Cunningham
|
||||
Sean McArthur
|
||||
Sean Silva
|
||||
Seong-Rak Choi
|
||||
Sergey Kholodilov
|
||||
Sergey Kryzhanovsky
|
||||
Seth Fitzsimmons
|
||||
Shannen Saez
|
||||
Shea Levy
|
||||
Shigeki Ohtsu
|
||||
Shuan Wang
|
||||
Shuhei Kagawa
|
||||
Siddharth Mahendraker
|
||||
Silas Sewell
|
||||
Simen Brekken
|
||||
Simon Cornelius P. Umacob
|
||||
Simon Sturmer
|
||||
Simon Willison
|
||||
Stanislav Ochotnicky
|
||||
Stanislav Opichal
|
||||
Stefan Bühler
|
||||
Stefan Rusu
|
||||
Stephen Gallagher
|
||||
Steve Engledow
|
||||
Steve Mao
|
||||
Steve Sharp
|
||||
Steven Kabbes
|
||||
Steven Loomis
|
||||
Steven R. Loomis
|
||||
Steven Rockarts
|
||||
Stiliyan Lazarov
|
||||
Stéphan Kochen
|
||||
Sugendran Ganess
|
||||
Suwon Chae
|
||||
Sven Panne
|
||||
Swaagie
|
||||
T.C. Hollingsworth
|
||||
TJ Holowaychuk
|
||||
Tadashi SAWADA
|
||||
Takahiro ANDO
|
||||
Taojie
|
||||
Ted Young
|
||||
Theo Schlossnagle
|
||||
Thom Seddon
|
||||
Thomas Lee
|
||||
Thomas Parslow
|
||||
Thomas Shinnick
|
||||
Thorsten Lorenz
|
||||
Tim Baumann
|
||||
Tim Bradshaw
|
||||
Tim Caswell
|
||||
Tim Cooijmans
|
||||
Tim Kuijsten
|
||||
Tim Macfarlane
|
||||
Tim Oxley
|
||||
Tim Price
|
||||
Tim Smart
|
||||
Tim Wood
|
||||
Timothy J Fontaine
|
||||
Tobias Müllerleile
|
||||
Tobie Langel
|
||||
Tom Gallacher
|
||||
Tom Hughes-Croucher
|
||||
Tomasz Buchert
|
||||
Tomasz Janczuk
|
||||
Tony Huang
|
||||
Tony Metzidis
|
||||
Toon Verwaest
|
||||
Toshihiro Nakamura
|
||||
Travis Swicegood
|
||||
Trent Mick
|
||||
Trevor Burnham
|
||||
Trevor Livingston
|
||||
Trevor Norris
|
||||
Tristan Berger
|
||||
Tuğrul Topuz
|
||||
Tyler Anton
|
||||
Tyler Larson
|
||||
Tyler Neylon
|
||||
Urban Hafner
|
||||
Veres Lajos
|
||||
Vicente Jimenez Aguilar
|
||||
Victor Costan
|
||||
Victor Widell
|
||||
Vincent Ollivier
|
||||
Vincent Voyer
|
||||
Vitali Lovich
|
||||
Vitor Balocco
|
||||
Vladimir Beloborodov
|
||||
Vladimir Kurchatkin
|
||||
Vsevolod Strukchinsky
|
||||
Vyacheslav Egorov
|
||||
Wade Simmons
|
||||
Wang Xinyong
|
||||
Willi Eggeling
|
||||
William Bert
|
||||
Wojciech Wnętrzak
|
||||
Wyatt Preul
|
||||
Xavi Magrinyà
|
||||
Xavier Shay
|
||||
Xidorn Quan
|
||||
Yang Guo
|
||||
Yazhong Liu
|
||||
Yiyu He
|
||||
Yoji SHIDARA
|
||||
Yorkie
|
||||
Yosef Dinerstein
|
||||
Yoshihiro KIKUCHI
|
||||
Yuan Chuan
|
||||
Yuichiro MASUI
|
||||
Yuki KAN
|
||||
Yunsong Guo
|
||||
Yuriy Nemtsov
|
||||
Yury Semikhatsky
|
||||
Zachary Scott
|
||||
Zarko Stankovic
|
||||
Zoran Tomicic
|
||||
adamk
|
||||
ayanamist
|
||||
fengmk2
|
||||
h7lin
|
||||
haoxin
|
||||
pflannery
|
||||
pkcs
|
||||
silverwind
|
||||
sudodoki
|
||||
Łukasz Walukiewicz
|
||||
# Authors ordered by first contribution.
|
||||
|
||||
Ryan Dahl <ry@tinyclouds.org>
|
||||
Urban Hafner <urban@bettong.net>
|
||||
Joshaven Potter <yourtech@gmail.com>
|
||||
Abe Fettig <abefettig@gmail.com>
|
||||
Kevin van Zonneveld <kevin@vanzonneveld.net>
|
||||
Michael Carter <cartermichael@gmail.com>
|
||||
Jeff Smick <sprsquish@gmail.com>
|
||||
Jon Crosby <jon@joncrosby.me>
|
||||
Felix Geisendörfer <felix@debuggable.com>
|
||||
Ray Morgan <rmorgan@zappos.com>
|
||||
Jérémy Lal <kapouer@melix.org>
|
||||
Isaac Z. Schlueter <i@izs.me>
|
||||
Brandon Beacher <brandon.beacher@gmail.com>
|
||||
Tim Caswell <tim@creationix.com>
|
||||
Connor Dunn <connorhd@gmail.com>
|
||||
Johan Sørensen <johan@johansorensen.com>
|
||||
Friedemann Altrock <frodenius@gmail.com>
|
||||
Onne Gorter <onne@onnlucky.com>
|
||||
Rhys Jones <rhys@wave.to>
|
||||
Jan Lehnardt <jan@apache.org>
|
||||
Simon Willison <simon@simonwillison.net>
|
||||
Chew Choon Keat <choonkeat@gmail.com>
|
||||
Jered Schmidt <tr@nslator.jp>
|
||||
Michaeljohn Clement <inimino@inimino.org>
|
||||
Karl Guertin <grayrest@gr.ayre.st>
|
||||
Xavier Shay <xavier@rhnh.net>
|
||||
Christopher Lenz <cmlenz@gmail.com>
|
||||
TJ Holowaychuk <tj@vision-media.ca>
|
||||
Johan Dahlberg <jfd@distrop.com>
|
||||
Simon Cornelius P. Umacob <simoncpu@gmail.com>
|
||||
Ryan McGrath <ryan@venodesigns.net>
|
||||
Rasmus Andersson <rasmus@notion.se>
|
||||
Micheil Smith <micheil@brandedcode.com>
|
||||
Jonas Pfenniger <jonas@pfenniger.name>
|
||||
David Sklar <david.sklar@gmail.com>
|
||||
Charles Lehner <celehner1@gmail.com>
|
||||
Elliott Cable <me@ell.io>
|
||||
Benjamin Thomas <benjamin@benjaminthomas.org>
|
||||
San-Tai Hsu <v@fatpipi.com>
|
||||
Ben Williamson <benw@pobox.com>
|
||||
Joseph Pecoraro <joepeck02@gmail.com>
|
||||
Erich Ocean <erich.ocean@me.com>
|
||||
Alexis Sellier <self@cloudhead.net>
|
||||
Blaine Cook <romeda@gmail.com>
|
||||
Stanislav Opichal <opichals@gmail.com>
|
||||
Aaron Heckmann <aaron.heckmann@gmail.com>
|
||||
Mikeal Rogers <mikeal.rogers@gmail.com>
|
||||
Matt Brubeck <mbrubeck@limpet.net>
|
||||
Michael Stillwell <mjs@beebo.org>
|
||||
Yuichiro MASUI <masui@masuidrive.jp>
|
||||
Mark Hansen <mark@markhansen.co.nz>
|
||||
Zoran Tomicic <ztomicic@gmail.com>
|
||||
Jeremy Ashkenas <jashkenas@gmail.com>
|
||||
Scott González <scott.gonzalez@gmail.com>
|
||||
James Duncan <james@joyent.com>
|
||||
Arlo Breault <arlolra@gmail.com>
|
||||
Kris Kowal <kris.kowal@cixar.com>
|
||||
Jacek Becela <jacek.becela@gmail.com>
|
||||
Rob Ellis <kazoomer@gmail.com>
|
||||
Tim Smart <timehAndGod@gmail.com>
|
||||
Herbert Vojčík <herby@mailbox.sk>
|
||||
Krishna Rajendran <krishna@emptybox.org>
|
||||
Nicholas Kinsey <pyrotechnick@feistystudios.com>
|
||||
Scott Taylor <scott@railsnewbie.com>
|
||||
Carson McDonald <carson@ioncannon.net>
|
||||
Matt Ranney <mjr@ranney.com>
|
||||
James Herdman <james.herdman@gmail.com>
|
||||
Julian Lamb <thepurlieu@gmail.com>
|
||||
Brian Hammond <brian@fictorial.com>
|
||||
Mathias Pettersson <mape@mape.me>
|
||||
Trevor Blackwell <tlb@tlb.org>
|
||||
Thomas Lee <thomas.lee@shinetech.com>
|
||||
Daniel Berger <code+node@dpbis.net>
|
||||
Paulo Matias <paulo.matias@usp.br>
|
||||
Peter Griess <pg@std.in>
|
||||
Jonathan Knezek <jdknezek@gmail.com>
|
||||
Jonathan Rentzsch <jwr.git@redshed.net>
|
||||
Ben Noordhuis <info@bnoordhuis.nl>
|
||||
Elijah Insua <tmpvar@gmail.com>
|
||||
Andrew Johnston <apjohnsto@gmail.com>
|
||||
Brian White <mscdex@mscdex.net>
|
||||
Aapo Laitinen <aapo.laitinen@iki.fi>
|
||||
Sam Hughes <sam@samuelhughes.com>
|
||||
Orlando Vazquez <ovazquez@gmail.com>
|
||||
Raffaele Sena <raff367@gmail.com>
|
||||
Brian McKenna <brian@brianmckenna.org>
|
||||
Paul Querna <pquerna@apache.org>
|
||||
Ben Lowery <ben@blowery.org>
|
||||
Peter Dekkers <soderblom.peter@gmail.com>
|
||||
David Siegel <david@artcom.de>
|
||||
Marshall Culpepper <marshall.law@gmail.com>
|
||||
Ruben Rodriguez <cha0s@therealcha0s.net>
|
||||
Dmitry Baranovskiy <Dmitry@Baranovskiy.com>
|
||||
Blake Mizerany <blake.mizerany@gmail.com>
|
||||
Jerome Etienne <jerome.etienne@gmail.com>
|
||||
Dmitriy Shalashov <skaurus@gmail.com>
|
||||
Adam Wiggins <adam@heroku.com>
|
||||
Rick Olson <technoweenie@gmail.com>
|
||||
David Siegel <david.siegel@artcom.de>
|
||||
Sergey Kzyzhanovsky <skryzhanovsky@gmail.com>
|
||||
Marco Rogers <marco.rogers@gmail.com>
|
||||
Benjamin Fritsch <beanie@benle.de>
|
||||
Jan Kassens <jan@kassens.net>
|
||||
Robert Keizer <root@black.bluerack.ca>
|
||||
Sam Shull <brickysam26@gmail.com>
|
||||
Chandra Sekar S <chandru.in@gmail.com>
|
||||
Andrew Naylor <argon@mkbot.net>
|
||||
Benjamin Kramer <benny.kra@gmail.com>
|
||||
Danny Coates <dannycoates@gmail.com>
|
||||
Samuel Shull <brickysam26@gmail.com>
|
||||
Nick Stenning <nick@whiteink.com>
|
||||
Bert Belder <bertbelder@gmail.com>
|
||||
Trent Mick <trentm@gmail.com>
|
||||
Fedor Indutny <fedor.indutny@gmail.com>
|
||||
Illarionov Oleg <oleg@emby.ru>
|
||||
Aria Stewart <aredridel@nbtsc.org>
|
||||
Johan Euphrosine <proppy@aminche.com>
|
||||
Russell Haering <russellhaering@gmail.com>
|
||||
Bradley Meck <bradley.meck@gmail.com>
|
||||
Tobie Langel <tobie.langel@gmail.com>
|
||||
Tony Metzidis <tonym@tonym.us>
|
||||
Jorge Chamorro Bieling <jorge@jorgechamorro.com>
|
||||
Evan Larkin <evan.larkin.il.com>
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
all:
|
||||
@echo "I need GNU make. Please run \`gmake\` instead."
|
||||
154
CONTRIBUTING.md
154
CONTRIBUTING.md
@@ -1,154 +0,0 @@
|
||||
# CONTRIBUTING
|
||||
|
||||
The node.js project welcomes new contributors. This document will guide you
|
||||
through the process.
|
||||
|
||||
|
||||
### FORK
|
||||
|
||||
Fork the project [on GitHub](https://github.com/joyent/node) and check out
|
||||
your copy.
|
||||
|
||||
```sh
|
||||
$ git clone git@github.com:username/node.git
|
||||
$ cd node
|
||||
$ git remote add upstream git://github.com/joyent/node.git
|
||||
```
|
||||
|
||||
Now decide if you want your feature or bug fix to go into the master branch
|
||||
or the stable branch. As a rule of thumb, bug fixes go into the stable branch
|
||||
while new features go into the master branch.
|
||||
|
||||
The stable branch is effectively frozen; patches that change the node.js
|
||||
API/ABI or affect the run-time behavior of applications get rejected.
|
||||
|
||||
The rules for the master branch are less strict; consult the
|
||||
[stability index page][] for details.
|
||||
|
||||
In a nutshell, modules are at varying levels of API stability. Bug fixes are
|
||||
always welcome but API or behavioral changes to modules at stability level 3
|
||||
and up are off-limits.
|
||||
|
||||
Node.js has several bundled dependencies in the deps/ and the tools/
|
||||
directories that are not part of the project proper. Any changes to files
|
||||
in those directories or its subdirectories should be sent to their respective
|
||||
projects. Do not send your patch to us, we cannot accept it.
|
||||
|
||||
In case of doubt, open an issue in the [issue tracker][], post your question
|
||||
to the [node.js mailing list][] or contact one of the [project maintainers][]
|
||||
on [IRC][].
|
||||
|
||||
Especially do so if you plan to work on something big. Nothing is more
|
||||
frustrating than seeing your hard work go to waste because your vision
|
||||
does not align with that of a project maintainer.
|
||||
|
||||
|
||||
### BRANCH
|
||||
|
||||
Okay, so you have decided on the proper branch. Create a feature branch
|
||||
and start hacking:
|
||||
|
||||
```sh
|
||||
$ git checkout -b my-feature-branch -t origin/v0.10
|
||||
```
|
||||
|
||||
(Where v0.10 is the latest stable branch as of this writing.)
|
||||
|
||||
|
||||
### COMMIT
|
||||
|
||||
Make sure git knows your name and email address:
|
||||
|
||||
```sh
|
||||
$ git config --global user.name "J. Random User"
|
||||
$ git config --global user.email "j.random.user@example.com"
|
||||
```
|
||||
|
||||
Writing good commit logs is important. A commit log should describe what
|
||||
changed and why. Follow these guidelines when writing one:
|
||||
|
||||
1. The first line should be 50 characters or less and contain a short
|
||||
description of the change prefixed with the name of the changed
|
||||
subsystem (e.g. "net: add localAddress and localPort to Socket").
|
||||
2. Keep the second line blank.
|
||||
3. Wrap all other lines at 72 columns.
|
||||
|
||||
A good commit log looks like this:
|
||||
|
||||
```
|
||||
subsystem: explaining the commit in one line
|
||||
|
||||
Body of commit message is a few lines of text, explaining things
|
||||
in more detail, possibly giving some background about the issue
|
||||
being fixed, etc etc.
|
||||
|
||||
The body of the commit message can be several paragraphs, and
|
||||
please do proper word-wrap and keep columns shorter than about
|
||||
72 characters or so. That way `git log` will show things
|
||||
nicely even when it is indented.
|
||||
```
|
||||
|
||||
The header line should be meaningful; it is what other people see when they
|
||||
run `git shortlog` or `git log --oneline`.
|
||||
|
||||
Check the output of `git log --oneline files_that_you_changed` to find out
|
||||
what subsystem (or subsystems) your changes touch.
|
||||
|
||||
|
||||
### REBASE
|
||||
|
||||
Use `git rebase` (not `git merge`) to sync your work from time to time.
|
||||
|
||||
```sh
|
||||
$ git fetch upstream
|
||||
$ git rebase upstream/v0.10 # or upstream/master
|
||||
```
|
||||
|
||||
|
||||
### TEST
|
||||
|
||||
Bug fixes and features should come with tests. Add your tests in the
|
||||
test/simple/ directory. Look at other tests to see how they should be
|
||||
structured (license boilerplate, common includes, etc.).
|
||||
|
||||
```sh
|
||||
$ make jslint test
|
||||
```
|
||||
|
||||
Make sure the linter is happy and that all tests pass. Please, do not submit
|
||||
patches that fail either check.
|
||||
|
||||
If you are updating tests and just want to run a single test to check it, you
|
||||
can use this syntax to run it exactly as the test harness would:
|
||||
|
||||
```
|
||||
python tools/test.py -v --mode=release simple/test-stream2-transform
|
||||
```
|
||||
|
||||
You can run tests directly with node:
|
||||
|
||||
```
|
||||
node ./test/simple/test-streams2-transform.js
|
||||
```
|
||||
|
||||
|
||||
### PUSH
|
||||
|
||||
```sh
|
||||
$ git push origin my-feature-branch
|
||||
```
|
||||
|
||||
Go to https://github.com/username/node and select your feature branch. Click
|
||||
the 'Pull Request' button and fill out the form.
|
||||
|
||||
Pull requests are usually reviewed within a few days. If there are comments
|
||||
to address, apply your changes in a separate commit and push that to your
|
||||
feature branch. Post a comment in the pull request afterwards; GitHub does
|
||||
not send out notifications when you add commits.
|
||||
|
||||
|
||||
[stability index page]: https://github.com/joyent/node/blob/master/doc/api/documentation.markdown
|
||||
[issue tracker]: https://github.com/joyent/node/issues
|
||||
[node.js mailing list]: http://groups.google.com/group/nodejs
|
||||
[IRC]: http://webchat.freenode.net/?channels=node.js
|
||||
[project maintainers]: https://github.com/joyent/node/wiki/Project-Organization
|
||||
476
Makefile
476
Makefile
@@ -1,456 +1,88 @@
|
||||
-include config.mk
|
||||
WAF=python tools/waf-light
|
||||
|
||||
BUILDTYPE ?= Release
|
||||
PYTHON ?= python
|
||||
NINJA ?= ninja
|
||||
DESTDIR ?=
|
||||
SIGN ?=
|
||||
PREFIX ?= /usr/local
|
||||
FLAKY_TESTS ?= run
|
||||
all:
|
||||
@$(WAF) build
|
||||
|
||||
NODE ?= ./node
|
||||
all-progress:
|
||||
@$(WAF) -p build
|
||||
|
||||
# Default to verbose builds.
|
||||
# To do quiet/pretty builds, run `make V=` to set V to an empty string,
|
||||
# or set the V environment variable to an empty string.
|
||||
V ?= 1
|
||||
|
||||
ifeq ($(USE_NINJA),1)
|
||||
ifneq ($(V),)
|
||||
NINJA := $(NINJA) -v
|
||||
endif
|
||||
endif
|
||||
|
||||
# BUILDTYPE=Debug builds both release and debug builds. If you want to compile
|
||||
# just the debug build, run `make -C out BUILDTYPE=Debug` instead.
|
||||
ifeq ($(BUILDTYPE),Release)
|
||||
all: out/Makefile node
|
||||
else
|
||||
all: out/Makefile node node_g
|
||||
endif
|
||||
|
||||
# The .PHONY is needed to ensure that we recursively use the out/Makefile
|
||||
# to check for changes.
|
||||
.PHONY: node node_g
|
||||
|
||||
ifeq ($(USE_NINJA),1)
|
||||
node: config.gypi
|
||||
$(NINJA) -C out/Release/
|
||||
ln -fs out/Release/node node
|
||||
|
||||
node_g: config.gypi
|
||||
$(NINJA) -C out/Debug/
|
||||
ln -fs out/Debug/node $@
|
||||
else
|
||||
node: config.gypi out/Makefile
|
||||
$(MAKE) -C out BUILDTYPE=Release V=$(V)
|
||||
ln -fs out/Release/node node
|
||||
|
||||
node_g: config.gypi out/Makefile
|
||||
$(MAKE) -C out BUILDTYPE=Debug V=$(V)
|
||||
ln -fs out/Debug/node $@
|
||||
endif
|
||||
|
||||
out/Makefile: common.gypi deps/uv/uv.gyp deps/http_parser/http_parser.gyp deps/zlib/zlib.gyp deps/v8/build/toolchain.gypi deps/v8/build/features.gypi deps/v8/tools/gyp/v8.gyp node.gyp config.gypi
|
||||
ifeq ($(USE_NINJA),1)
|
||||
touch out/Makefile
|
||||
$(PYTHON) tools/gyp_node.py -f ninja
|
||||
else
|
||||
$(PYTHON) tools/gyp_node.py -f make
|
||||
endif
|
||||
|
||||
config.gypi: configure
|
||||
if [ -f $@ ]; then
|
||||
$(error Stale $@, please re-run ./configure)
|
||||
else
|
||||
$(error No $@, please run ./configure first)
|
||||
fi
|
||||
|
||||
install: all
|
||||
$(PYTHON) tools/install.py $@ '$(DESTDIR)' '$(PREFIX)'
|
||||
install:
|
||||
@$(WAF) install
|
||||
|
||||
uninstall:
|
||||
$(PYTHON) tools/install.py $@ '$(DESTDIR)' '$(PREFIX)'
|
||||
|
||||
clean:
|
||||
-rm -rf out/Makefile node node_g out/$(BUILDTYPE)/node blog.html email.md
|
||||
-find out/ -name '*.o' -o -name '*.a' | xargs rm -rf
|
||||
-rm -rf node_modules
|
||||
|
||||
distclean:
|
||||
-rm -rf out
|
||||
-rm -f config.gypi icu_config.gypi
|
||||
-rm -f config.mk
|
||||
-rm -rf node node_g blog.html email.md
|
||||
-rm -rf node_modules
|
||||
-rm -rf deps/icu
|
||||
-rm -rf deps/icu4c*.tgz deps/icu4c*.zip deps/icu-tmp
|
||||
@$(WAF) uninstall
|
||||
|
||||
test: all
|
||||
$(PYTHON) tools/test.py --mode=release simple message
|
||||
$(MAKE) jslint
|
||||
$(MAKE) cpplint
|
||||
python tools/test.py --mode=release simple message
|
||||
|
||||
test-http1: all
|
||||
$(PYTHON) tools/test.py --mode=release --use-http1 simple message
|
||||
test-all: all
|
||||
python tools/test.py --mode=debug,release
|
||||
|
||||
test-valgrind: all
|
||||
$(PYTHON) tools/test.py --mode=release --valgrind simple message
|
||||
test-release: all
|
||||
python tools/test.py --mode=release
|
||||
|
||||
test/gc/node_modules/weak/build/Release/weakref.node:
|
||||
@if [ ! -f node ]; then make all; fi
|
||||
./node deps/npm/node_modules/node-gyp/bin/node-gyp rebuild \
|
||||
--directory="$(shell pwd)/test/gc/node_modules/weak" \
|
||||
--nodedir="$(shell pwd)"
|
||||
test-debug: all
|
||||
python tools/test.py --mode=debug
|
||||
|
||||
build-addons:
|
||||
@if [ ! -f node ]; then make all; fi
|
||||
rm -rf test/addons/doc-*/
|
||||
./node tools/doc/addon-verify.js
|
||||
$(foreach dir, \
|
||||
$(sort $(dir $(wildcard test/addons/*/*.gyp))), \
|
||||
./node deps/npm/node_modules/node-gyp/bin/node-gyp rebuild \
|
||||
--directory="$(shell pwd)/$(dir)" \
|
||||
--nodedir="$(shell pwd)" && ) echo "build done"
|
||||
|
||||
test-gc: all test/gc/node_modules/weak/build/Release/weakref.node
|
||||
$(PYTHON) tools/test.py --mode=release gc
|
||||
|
||||
test-build: all build-addons
|
||||
|
||||
test-all: test-build test/gc/node_modules/weak/build/Release/weakref.node
|
||||
$(PYTHON) tools/test.py --mode=debug,release
|
||||
make test-npm
|
||||
|
||||
test-all-http1: test-build
|
||||
$(PYTHON) tools/test.py --mode=debug,release --use-http1
|
||||
|
||||
test-all-valgrind: test-build
|
||||
$(PYTHON) tools/test.py --mode=debug,release --valgrind
|
||||
|
||||
test-ci:
|
||||
$(PYTHON) tools/test.py -p tap --logfile test.tap --mode=release --arch=$(DESTCPU) --flaky-tests=$(FLAKY_TESTS) simple message internet
|
||||
|
||||
test-release: test-build
|
||||
$(PYTHON) tools/test.py --mode=release
|
||||
|
||||
test-debug: test-build
|
||||
$(PYTHON) tools/test.py --mode=debug
|
||||
|
||||
test-message: test-build
|
||||
$(PYTHON) tools/test.py message
|
||||
test-message: all
|
||||
python tools/test.py message
|
||||
|
||||
test-simple: all
|
||||
$(PYTHON) tools/test.py simple
|
||||
|
||||
test-pummel: all wrk
|
||||
$(PYTHON) tools/test.py pummel
|
||||
|
||||
python tools/test.py simple
|
||||
|
||||
test-pummel: all
|
||||
python tools/test.py pummel
|
||||
|
||||
test-internet: all
|
||||
$(PYTHON) tools/test.py internet
|
||||
python tools/test.py internet
|
||||
|
||||
test-debugger: all
|
||||
$(PYTHON) tools/test.py debugger
|
||||
benchmark: all
|
||||
build/default/node benchmark/run.js
|
||||
|
||||
test-npm: node
|
||||
rm -rf npm-cache npm-tmp npm-prefix
|
||||
mkdir npm-cache npm-tmp npm-prefix
|
||||
cd deps/npm ; npm_config_cache="$(shell pwd)/npm-cache" \
|
||||
npm_config_prefix="$(shell pwd)/npm-prefix" \
|
||||
npm_config_tmp="$(shell pwd)/npm-tmp" \
|
||||
PATH="../../:${PATH}" node cli.js install
|
||||
cd deps/npm ; npm_config_cache="$(shell pwd)/npm-cache" \
|
||||
npm_config_prefix="$(shell pwd)/npm-prefix" \
|
||||
npm_config_tmp="$(shell pwd)/npm-tmp" \
|
||||
PATH="../../:${PATH}" node cli.js run-script test-legacy && \
|
||||
PATH="../../:${PATH}" node cli.js run-script test && \
|
||||
PATH="../../:${PATH}" node cli.js prune --prod && \
|
||||
cd ../.. && \
|
||||
rm -rf npm-cache npm-tmp npm-prefix
|
||||
# http://rtomayko.github.com/ronn
|
||||
# gem install ronn
|
||||
doc: doc/node.1 doc/api.html doc/index.html doc/changelog.html
|
||||
|
||||
test-npm-publish: node
|
||||
npm_package_config_publishtest=true ./node deps/npm/test/run.js
|
||||
## HACK to give the ronn-generated page a TOC
|
||||
doc/api.html: all doc/api.markdown doc/api_header.html doc/api_footer.html
|
||||
build/default/node tools/ronnjs/bin/ronn.js --fragment doc/api.markdown \
|
||||
| sed "s/<h2>\(.*\)<\/h2>/<h2 id=\"\1\">\1<\/h2>/g" \
|
||||
| cat doc/api_header.html - doc/api_footer.html > doc/api.html
|
||||
|
||||
test-addons: test-build
|
||||
$(PYTHON) tools/test.py --mode=release addons
|
||||
doc/changelog.html: ChangeLog doc/changelog_header.html doc/changelog_footer.html
|
||||
cat doc/changelog_header.html ChangeLog doc/changelog_footer.html > doc/changelog.html
|
||||
|
||||
test-timers:
|
||||
$(MAKE) --directory=tools faketime
|
||||
$(PYTHON) tools/test.py --mode=release timers
|
||||
|
||||
test-timers-clean:
|
||||
$(MAKE) --directory=tools clean
|
||||
|
||||
apidoc_sources = $(wildcard doc/api/*.markdown)
|
||||
apidocs = $(addprefix out/,$(apidoc_sources:.markdown=.html)) \
|
||||
$(addprefix out/,$(apidoc_sources:.markdown=.json))
|
||||
|
||||
apidoc_dirs = out/doc out/doc/api/ out/doc/api/assets
|
||||
|
||||
apiassets = $(subst api_assets,api/assets,$(addprefix out/,$(wildcard doc/api_assets/*)))
|
||||
|
||||
website_files = \
|
||||
out/doc/sh_main.js \
|
||||
out/doc/sh_javascript.min.js
|
||||
|
||||
doc: $(apidoc_dirs) $(website_files) $(apiassets) $(apidocs) tools/doc/ out/doc/changelog.html node
|
||||
|
||||
doc-branch: NODE_DOC_VERSION = v$(shell $(PYTHON) tools/getnodeversion.py | cut -f1,2 -d.)
|
||||
doc-branch: doc
|
||||
|
||||
$(apidoc_dirs):
|
||||
mkdir -p $@
|
||||
|
||||
out/doc/api/assets/%: doc/api_assets/% out/doc/api/assets/
|
||||
cp $< $@
|
||||
|
||||
out/doc/changelog.html: ChangeLog doc/changelog-head.html doc/changelog-foot.html tools/build-changelog.sh node
|
||||
bash tools/build-changelog.sh
|
||||
|
||||
out/doc/%: doc/%
|
||||
cp -r $< $@
|
||||
|
||||
out/doc/api/%.json: doc/api/%.markdown node
|
||||
NODE_DOC_VERSION=$(NODE_DOC_VERSION) out/Release/node tools/doc/generate.js --format=json $< > $@
|
||||
|
||||
out/doc/api/%.html: doc/api/%.markdown node
|
||||
NODE_DOC_VERSION=$(NODE_DOC_VERSION) out/Release/node tools/doc/generate.js --format=html --template=doc/template.html $< > $@
|
||||
|
||||
email.md: ChangeLog tools/email-footer.md
|
||||
bash tools/changelog-head.sh | sed 's|^\* #|* \\#|g' > $@
|
||||
cat tools/email-footer.md | sed -e 's|__VERSION__|'$(VERSION)'|g' >> $@
|
||||
|
||||
blog.html: email.md
|
||||
cat $< | ./node tools/doc/node_modules/.bin/marked > $@
|
||||
doc/node.1: doc/api.markdown all
|
||||
build/default/node tools/ronnjs/bin/ronn.js --roff doc/api.markdown > doc/node.1
|
||||
|
||||
website-upload: doc
|
||||
rsync -r out/doc/ node@nodejs.org:~/web/nodejs.org/
|
||||
ssh node@nodejs.org '\
|
||||
rm -f ~/web/nodejs.org/dist/latest &&\
|
||||
ln -s $(VERSION) ~/web/nodejs.org/dist/latest &&\
|
||||
rm -f ~/web/nodejs.org/docs/latest &&\
|
||||
ln -s $(VERSION) ~/web/nodejs.org/docs/latest &&\
|
||||
rm -f ~/web/nodejs.org/dist/node-latest.tar.gz &&\
|
||||
ln -s $(VERSION)/node-$(VERSION).tar.gz ~/web/nodejs.org/dist/node-latest.tar.gz'
|
||||
|
||||
doc-branch-upload: NODE_DOC_VERSION = v$(shell $(PYTHON) tools/getnodeversion.py | cut -f1,2 -d.)
|
||||
doc-branch-upload: doc-branch
|
||||
echo $(NODE_DOC_VERSION)
|
||||
rsync -r out/doc/api/ node@nodejs.org:~/web/nodejs.org/$(NODE_DOC_VERSION)
|
||||
|
||||
docopen: out/doc/api/all.html
|
||||
-google-chrome out/doc/api/all.html
|
||||
scp doc/* ryan@nodejs.org:~/web/nodejs.org/
|
||||
|
||||
docclean:
|
||||
-rm -rf out/doc
|
||||
@-rm -f doc/node.1 doc/api.html doc/changelog.html
|
||||
|
||||
run-ci:
|
||||
$(PYTHON) ./configure --without-snapshot $(CONFIG_FLAGS)
|
||||
$(MAKE)
|
||||
$(MAKE) test-ci
|
||||
clean:
|
||||
@$(WAF) clean
|
||||
@-find tools -name "*.pyc" | xargs rm -f
|
||||
|
||||
RAWVER=$(shell $(PYTHON) tools/getnodeversion.py)
|
||||
VERSION=v$(RAWVER)
|
||||
NODE_DOC_VERSION=$(VERSION)
|
||||
RELEASE=$(shell $(PYTHON) tools/getnodeisrelease.py)
|
||||
PLATFORM=$(shell uname | tr '[:upper:]' '[:lower:]')
|
||||
ifeq ($(findstring x86_64,$(shell uname -m)),x86_64)
|
||||
DESTCPU ?= x64
|
||||
else
|
||||
DESTCPU ?= ia32
|
||||
endif
|
||||
ifeq ($(DESTCPU),x64)
|
||||
ARCH=x64
|
||||
else
|
||||
ifeq ($(DESTCPU),arm)
|
||||
ARCH=arm
|
||||
else
|
||||
ARCH=x86
|
||||
endif
|
||||
endif
|
||||
distclean: docclean
|
||||
@-find tools -name "*.pyc" | xargs rm -f
|
||||
@-rm -rf build/ node node_g
|
||||
|
||||
check:
|
||||
@tools/waf-light check
|
||||
|
||||
VERSION=$(shell git describe)
|
||||
TARNAME=node-$(VERSION)
|
||||
ifdef NIGHTLY
|
||||
TAG = nightly-$(NIGHTLY)
|
||||
TARNAME=node-$(VERSION)-$(TAG)
|
||||
endif
|
||||
TARBALL=$(TARNAME).tar.gz
|
||||
BINARYNAME=$(TARNAME)-$(PLATFORM)-$(ARCH)
|
||||
BINARYTAR=$(BINARYNAME).tar.gz
|
||||
PKG=out/$(TARNAME).pkg
|
||||
PACKAGEMAKER ?= /Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker
|
||||
|
||||
PKGSRC=nodejs-$(DESTCPU)-$(RAWVER).tgz
|
||||
ifdef NIGHTLY
|
||||
PKGSRC=nodejs-$(DESTCPU)-$(RAWVER)-$(TAG).tgz
|
||||
endif
|
||||
|
||||
dist: doc $(TARBALL) $(PKG)
|
||||
|
||||
PKGDIR=out/dist-osx
|
||||
|
||||
release-only:
|
||||
@if [ "$(shell git status --porcelain | egrep -v '^\?\? ')" = "" ]; then \
|
||||
exit 0 ; \
|
||||
else \
|
||||
echo "" >&2 ; \
|
||||
echo "The git repository is not clean." >&2 ; \
|
||||
echo "Please commit changes before building release tarball." >&2 ; \
|
||||
echo "" >&2 ; \
|
||||
git status --porcelain | egrep -v '^\?\?' >&2 ; \
|
||||
echo "" >&2 ; \
|
||||
exit 1 ; \
|
||||
fi
|
||||
@if [ "$(NIGHTLY)" != "" -o "$(RELEASE)" = "1" ]; then \
|
||||
exit 0; \
|
||||
else \
|
||||
echo "" >&2 ; \
|
||||
echo "#NODE_VERSION_IS_RELEASE is set to $(RELEASE)." >&2 ; \
|
||||
echo "Did you remember to update src/node_version.cc?" >&2 ; \
|
||||
echo "" >&2 ; \
|
||||
exit 1 ; \
|
||||
fi
|
||||
|
||||
pkg: $(PKG)
|
||||
|
||||
$(PKG): release-only
|
||||
rm -rf $(PKGDIR)
|
||||
rm -rf out/deps out/Release
|
||||
$(PYTHON) ./configure --download=all --with-intl=small-icu \
|
||||
--without-snapshot --dest-cpu=ia32 --tag=$(TAG)
|
||||
$(MAKE) install V=$(V) DESTDIR=$(PKGDIR)/32
|
||||
rm -rf out/deps out/Release
|
||||
$(PYTHON) ./configure --download=all --with-intl=small-icu \
|
||||
--without-snapshot --dest-cpu=x64 --tag=$(TAG)
|
||||
$(MAKE) install V=$(V) DESTDIR=$(PKGDIR)
|
||||
SIGN="$(APP_SIGN)" PKGDIR="$(PKGDIR)" bash tools/osx-codesign.sh
|
||||
lipo $(PKGDIR)/32/usr/local/bin/node \
|
||||
$(PKGDIR)/usr/local/bin/node \
|
||||
-output $(PKGDIR)/usr/local/bin/node-universal \
|
||||
-create
|
||||
mv $(PKGDIR)/usr/local/bin/node-universal $(PKGDIR)/usr/local/bin/node
|
||||
rm -rf $(PKGDIR)/32
|
||||
$(PACKAGEMAKER) \
|
||||
--id "org.nodejs.Node" \
|
||||
--doc tools/osx-pkg.pmdoc \
|
||||
--out $(PKG)
|
||||
SIGN="$(INT_SIGN)" PKG="$(PKG)" bash tools/osx-productsign.sh
|
||||
|
||||
$(TARBALL): release-only node doc
|
||||
dist: doc/node.1 doc/api.html
|
||||
git archive --format=tar --prefix=$(TARNAME)/ HEAD | tar xf -
|
||||
mkdir -p $(TARNAME)/doc/api
|
||||
mkdir -p $(TARNAME)/doc
|
||||
cp doc/node.1 $(TARNAME)/doc/node.1
|
||||
cp -r out/doc/api/* $(TARNAME)/doc/api/
|
||||
cp doc/api.html $(TARNAME)/doc/api.html
|
||||
rm -rf $(TARNAME)/deps/v8/test # too big
|
||||
rm -rf $(TARNAME)/doc/images # too big
|
||||
find $(TARNAME)/ -type l | xargs rm # annoying on windows
|
||||
tar -cf $(TARNAME).tar $(TARNAME)
|
||||
rm -rf $(TARNAME)
|
||||
gzip -f -9 $(TARNAME).tar
|
||||
|
||||
tar: $(TARBALL)
|
||||
|
||||
$(BINARYTAR): release-only
|
||||
rm -rf $(BINARYNAME)
|
||||
rm -rf out/deps out/Release
|
||||
$(PYTHON) ./configure --prefix=/ --download=all --with-intl=small-icu \
|
||||
--without-snapshot --dest-cpu=$(DESTCPU) --tag=$(TAG) $(CONFIG_FLAGS)
|
||||
$(MAKE) install DESTDIR=$(BINARYNAME) V=$(V) PORTABLE=1
|
||||
cp README.md $(BINARYNAME)
|
||||
cp LICENSE $(BINARYNAME)
|
||||
cp ChangeLog $(BINARYNAME)
|
||||
tar -cf $(BINARYNAME).tar $(BINARYNAME)
|
||||
rm -rf $(BINARYNAME)
|
||||
gzip -f -9 $(BINARYNAME).tar
|
||||
|
||||
binary: $(BINARYTAR)
|
||||
|
||||
$(PKGSRC): release-only
|
||||
rm -rf dist out
|
||||
$(PYTHON) configure --prefix=/ --without-snapshot --download=all \
|
||||
--with-intl=small-icu --dest-cpu=$(DESTCPU) --tag=$(TAG) \
|
||||
$(CONFIG_FLAGS)
|
||||
$(MAKE) install DESTDIR=dist
|
||||
(cd dist; find * -type f | sort) > packlist
|
||||
pkg_info -X pkg_install | \
|
||||
egrep '^(MACHINE_ARCH|OPSYS|OS_VERSION|PKGTOOLS_VERSION)' > build-info
|
||||
pkg_create -B build-info -c tools/pkgsrc/comment -d tools/pkgsrc/description \
|
||||
-f packlist -I /opt/local -p dist -U $(PKGSRC)
|
||||
|
||||
pkgsrc: $(PKGSRC)
|
||||
|
||||
dist-upload: $(TARBALL) $(PKG)
|
||||
ssh node@nodejs.org mkdir -p web/nodejs.org/dist/$(VERSION)
|
||||
scp $(TARBALL) node@nodejs.org:~/web/nodejs.org/dist/$(VERSION)/$(TARBALL)
|
||||
scp $(PKG) node@nodejs.org:~/web/nodejs.org/dist/$(VERSION)/$(TARNAME).pkg
|
||||
|
||||
wrkclean:
|
||||
$(MAKE) -C tools/wrk/ clean
|
||||
rm tools/wrk/wrk
|
||||
|
||||
wrk: tools/wrk/wrk
|
||||
tools/wrk/wrk:
|
||||
$(MAKE) -C tools/wrk/
|
||||
|
||||
bench-net: all
|
||||
@$(NODE) benchmark/common.js net
|
||||
|
||||
bench-crypto: all
|
||||
@$(NODE) benchmark/common.js crypto
|
||||
|
||||
bench-tls: all
|
||||
@$(NODE) benchmark/common.js tls
|
||||
|
||||
bench-http: wrk all
|
||||
@$(NODE) benchmark/common.js http
|
||||
|
||||
bench-fs: all
|
||||
@$(NODE) benchmark/common.js fs
|
||||
|
||||
bench-misc: all
|
||||
@$(MAKE) -C benchmark/misc/function_call/
|
||||
@$(NODE) benchmark/common.js misc
|
||||
|
||||
bench-array: all
|
||||
@$(NODE) benchmark/common.js arrays
|
||||
|
||||
bench-buffer: all
|
||||
@$(NODE) benchmark/common.js buffers
|
||||
|
||||
bench-all: bench bench-misc bench-array bench-buffer
|
||||
|
||||
bench: bench-net bench-http bench-fs bench-tls
|
||||
|
||||
bench-http-simple:
|
||||
benchmark/http_simple_bench.sh
|
||||
|
||||
bench-idle:
|
||||
./node benchmark/idle_server.js &
|
||||
sleep 1
|
||||
./node benchmark/idle_clients.js &
|
||||
|
||||
jslintfix:
|
||||
PYTHONPATH=tools/closure_linter/ $(PYTHON) tools/closure_linter/closure_linter/fixjsstyle.py --strict --nojsdoc -r lib/ -r src/ --exclude_files lib/punycode.js
|
||||
|
||||
jslint:
|
||||
PYTHONPATH=tools/closure_linter/ $(PYTHON) tools/closure_linter/closure_linter/gjslint.py --unix_mode --strict --nojsdoc -r lib/ -r src/ --exclude_files lib/punycode.js
|
||||
|
||||
CPPLINT_EXCLUDE ?=
|
||||
CPPLINT_EXCLUDE += src/node_root_certs.h
|
||||
CPPLINT_EXCLUDE += src/node_win32_perfctr_provider.cc
|
||||
CPPLINT_EXCLUDE += src/queue.h
|
||||
CPPLINT_EXCLUDE += src/tree.h
|
||||
CPPLINT_EXCLUDE += src/v8abbr.h
|
||||
|
||||
CPPLINT_FILES = $(filter-out $(CPPLINT_EXCLUDE), $(wildcard src/*.cc src/*.h src/*.c tools/icu/*.h tools/icu/*.cc deps/debugger-agent/include/* deps/debugger-agent/src/*))
|
||||
|
||||
cpplint:
|
||||
@$(PYTHON) tools/cpplint.py $(CPPLINT_FILES)
|
||||
|
||||
lint: jslint cpplint
|
||||
|
||||
.PHONY: lint cpplint jslint bench clean docopen docclean doc dist distclean \
|
||||
check uninstall install install-includes install-bin all staticlib \
|
||||
dynamiclib test test-all test-addons build-addons website-upload pkg \
|
||||
blog blogclean tar binary release-only bench-http-simple bench-idle \
|
||||
bench-all bench bench-misc bench-array bench-buffer bench-net \
|
||||
bench-http bench-fs bench-tls run-ci
|
||||
.PHONY: benchmark clean docclean dist distclean check uninstall install all test test-all website-upload
|
||||
|
||||
24
README
Normal file
24
README
Normal file
@@ -0,0 +1,24 @@
|
||||
Evented I/O for V8 javascript.
|
||||
|
||||
To build:
|
||||
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
To run the tests:
|
||||
|
||||
make test
|
||||
|
||||
To build the documentation:
|
||||
|
||||
make doc
|
||||
|
||||
To read the documentation:
|
||||
|
||||
man doc/node.1
|
||||
|
||||
See http://nodejs.org/ for more information. For help and discussion
|
||||
subscribe to the mailing list by visiting
|
||||
http://groups.google.com/group/nodejs or by sending an email to
|
||||
nodejs+subscribe@googlegroups.com.
|
||||
@@ -1,200 +0,0 @@
|
||||
Evented I/O for V8 javascript.
|
||||
===
|
||||
|
||||
### To build:
|
||||
|
||||
Prerequisites (Unix only):
|
||||
|
||||
* GCC 4.2 or newer
|
||||
* G++ 4.2 or newer
|
||||
* Python 2.6 or 2.7
|
||||
* GNU Make 3.81 or newer
|
||||
* libexecinfo (FreeBSD and OpenBSD only)
|
||||
|
||||
Unix/Macintosh:
|
||||
|
||||
```sh
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
```
|
||||
|
||||
If your python binary is in a non-standard location or has a
|
||||
non-standard name, run the following instead:
|
||||
|
||||
```sh
|
||||
export PYTHON=/path/to/python
|
||||
$PYTHON ./configure
|
||||
make
|
||||
make install
|
||||
```
|
||||
|
||||
Prerequisites (Windows only):
|
||||
|
||||
* Python 2.6 or 2.7
|
||||
* Visual Studio 2010 or 2012
|
||||
|
||||
Windows:
|
||||
|
||||
```sh
|
||||
vcbuild nosign
|
||||
```
|
||||
|
||||
You can download pre-built binaries for various operating systems from
|
||||
[http://nodejs.org/download/](http://nodejs.org/download/). The Windows
|
||||
and OS X installers will prompt you for the location in which to install.
|
||||
The tarballs are self-contained; you can extract them to a local directory
|
||||
with:
|
||||
|
||||
```sh
|
||||
tar xzf /path/to/node-<version>-<platform>-<arch>.tar.gz
|
||||
```
|
||||
|
||||
Or system-wide with:
|
||||
|
||||
```sh
|
||||
cd /usr/local && tar --strip-components 1 -xzf \
|
||||
/path/to/node-<version>-<platform>-<arch>.tar.gz
|
||||
```
|
||||
|
||||
### To run the tests:
|
||||
|
||||
Unix/Macintosh:
|
||||
|
||||
```sh
|
||||
make test
|
||||
```
|
||||
|
||||
Windows:
|
||||
|
||||
```sh
|
||||
vcbuild test
|
||||
```
|
||||
|
||||
### To build the documentation:
|
||||
|
||||
```sh
|
||||
make doc
|
||||
```
|
||||
|
||||
### To read the documentation:
|
||||
|
||||
```sh
|
||||
man doc/node.1
|
||||
```
|
||||
|
||||
### `Intl` (ECMA-402) support:
|
||||
|
||||
[Intl](https://github.com/joyent/node/wiki/Intl) support is not
|
||||
enabled by default.
|
||||
|
||||
#### "small" (English only) support
|
||||
|
||||
This option will build with "small" (English only) support, but
|
||||
the full `Intl` (ECMA-402) APIs. With `--download=all` it will
|
||||
download the ICU library as needed.
|
||||
|
||||
Unix/Macintosh:
|
||||
|
||||
```sh
|
||||
./configure --with-intl=small-icu --download=all
|
||||
```
|
||||
|
||||
Windows:
|
||||
|
||||
```sh
|
||||
vcbuild small-icu download-all
|
||||
```
|
||||
|
||||
The `small-icu` mode builds
|
||||
with English-only data. You can add full data at runtime.
|
||||
|
||||
*Note:* more docs are on
|
||||
[the wiki](https://github.com/joyent/node/wiki/Intl).
|
||||
|
||||
#### Build with full ICU support (all locales supported by ICU):
|
||||
|
||||
With the `--download=all`, this may download ICU if you don't
|
||||
have an ICU in `deps/icu`.
|
||||
|
||||
Unix/Macintosh:
|
||||
|
||||
```sh
|
||||
./configure --with-intl=full-icu --download=all
|
||||
```
|
||||
|
||||
Windows:
|
||||
|
||||
```sh
|
||||
vcbuild full-icu download-all
|
||||
```
|
||||
|
||||
#### Build with no Intl support `:-(`
|
||||
|
||||
The `Intl` object will not be available.
|
||||
This is the default at present, so this option is not normally needed.
|
||||
|
||||
Unix/Macintosh:
|
||||
|
||||
```sh
|
||||
./configure --with-intl=none
|
||||
```
|
||||
|
||||
Windows:
|
||||
|
||||
```sh
|
||||
vcbuild intl-none
|
||||
```
|
||||
|
||||
#### Use existing installed ICU (Unix/Macintosh only):
|
||||
|
||||
```sh
|
||||
pkg-config --modversion icu-i18n && ./configure --with-intl=system-icu
|
||||
```
|
||||
|
||||
#### Build with a specific ICU:
|
||||
|
||||
You can find other ICU releases at
|
||||
[the ICU homepage](http://icu-project.org/download).
|
||||
Download the file named something like `icu4c-**##.#**-src.tgz` (or
|
||||
`.zip`).
|
||||
|
||||
Unix/Macintosh: from an already-unpacked ICU
|
||||
|
||||
```sh
|
||||
./configure --with-intl=[small-icu,full-icu] --with-icu-source=/path/to/icu
|
||||
```
|
||||
|
||||
Unix/Macintosh: from a local ICU tarball
|
||||
|
||||
```sh
|
||||
./configure --with-intl=[small-icu,full-icu] --with-icu-source=/path/to/icu.tgz
|
||||
```
|
||||
|
||||
Unix/Macintosh: from a tarball URL
|
||||
|
||||
```sh
|
||||
./configure --with-intl=full-icu --with-icu-source=http://url/to/icu.tgz
|
||||
```
|
||||
|
||||
Windows: first unpack latest ICU to `deps/icu`
|
||||
[icu4c-**##.#**-src.tgz](http://icu-project.org/download) (or `.zip`)
|
||||
as `deps/icu` (You'll have: `deps/icu/source/...`)
|
||||
|
||||
```sh
|
||||
vcbuild full-icu
|
||||
```
|
||||
|
||||
Resources for Newcomers
|
||||
---
|
||||
- [The Wiki](https://github.com/joyent/node/wiki)
|
||||
- [nodejs.org](http://nodejs.org/)
|
||||
- [how to install node.js and npm (node package manager)](http://www.joyent.com/blog/installing-node-and-npm/)
|
||||
- [list of modules](https://github.com/joyent/node/wiki/modules)
|
||||
- [searching the npm registry](http://npmjs.org/)
|
||||
- [list of companies and projects using node](https://github.com/joyent/node/wiki/Projects,-Applications,-and-Companies-Using-Node)
|
||||
- [node.js mailing list](http://groups.google.com/group/nodejs)
|
||||
- [irc chatroom, #node.js on freenode.net](http://webchat.freenode.net?channels=node.js&uio=d4)
|
||||
- [community](https://github.com/joyent/node/wiki/Community)
|
||||
- [contributing](https://github.com/joyent/node/wiki/Contributing)
|
||||
- [big list of all the helpful wiki pages](https://github.com/joyent/node/wiki/_pages)
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
This repository is an archive of Node.js before the move to [nodejs/node](https://github.com/nodejs/node).
|
||||
|
||||
It still contains issues and pull requests that are relevant to Node versions v0.10 and v0.12, and that were opened before the move to [nodejs/node](https://github.com/nodejs/node).
|
||||
New issues and pull requests, for all branches, should be opened at [nodejs/node](https://github.com/nodejs/node).
|
||||
New issues and pull requests opened here will automatically be rejected.
|
||||
|
||||
The pre-convergence version of the README is available [here](https://github.com/nodejs/node-v0.x-archive/blob/master/README-pre-convergence.md).
|
||||
22
TODO
Normal file
22
TODO
Normal file
@@ -0,0 +1,22 @@
|
||||
- tmp directory test/tmp for all files created during tests.
|
||||
- fix tests for NODE_MODULE_CONTEXTS=1
|
||||
- readline
|
||||
- fix for two column glyphs. use Markus Kuhn's wcwidth.c
|
||||
- fix for commands that extend beyond term width
|
||||
- SSL should be factored out of net.js into standalone stream object
|
||||
- add completion callbacks to all stream write() methods
|
||||
- Erradicate all traces of 'binary' encoding. Only used, now, in OpenSSL
|
||||
binding.
|
||||
- Documentation needs a major refactor; should generate more than one HTML
|
||||
page/man page from the single api.markdown file. Deep sections should be
|
||||
allowed.
|
||||
- debug and production modes
|
||||
- EventSource branch merged
|
||||
- TCP servers should have an optional number of maximum connections. When
|
||||
the maximum is reached it stops accepting new connections.
|
||||
- compile under clang
|
||||
- Use C++ style casts everywhere.
|
||||
- fs.readFile[Sync] should not call stat() and use the length.
|
||||
Test on Linux's /proc/sys/kernel/hostname
|
||||
- Ruby-like Process#detach (is that possible?)
|
||||
- stderr isn't flushing on exit
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
export TOOLCHAIN=$PWD/android-toolchain
|
||||
mkdir -p $TOOLCHAIN
|
||||
$1/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=arm-linux-androideabi-4.7 \
|
||||
--arch=arm \
|
||||
--install-dir=$TOOLCHAIN \
|
||||
--platform=android-9
|
||||
export PATH=$TOOLCHAIN/bin:$PATH
|
||||
export AR=arm-linux-androideabi-ar
|
||||
export CC=arm-linux-androideabi-gcc
|
||||
export CXX=arm-linux-androideabi-g++
|
||||
export LINK=arm-linux-androideabi-g++
|
||||
|
||||
./configure \
|
||||
--without-snapshot \
|
||||
--dest-cpu=arm \
|
||||
--dest-os=android
|
||||
@@ -1,115 +0,0 @@
|
||||
# Node.js core benchmark tests
|
||||
|
||||
This folder contains benchmark tests to measure the performance for certain
|
||||
Node.js APIs.
|
||||
|
||||
## How to run tests
|
||||
|
||||
There are two ways to run benchmark tests:
|
||||
|
||||
1. Run all tests of a given type, for example, buffers
|
||||
|
||||
```sh
|
||||
node benchmark/common.js buffers
|
||||
```
|
||||
|
||||
The above command will find all scripts under `buffers` directory and require
|
||||
each of them as a module. When a test script is required, it creates an instance
|
||||
of `Benchmark` (a class defined in common.js). In the next tick, the `Benchmark`
|
||||
constructor iterates through the configuration object property values and run
|
||||
the test function with each of the combined arguments in spawned processes. For
|
||||
example, buffers/buffer-read.js has the following configuration:
|
||||
|
||||
```js
|
||||
var bench = common.createBenchmark(main, {
|
||||
noAssert: [false, true],
|
||||
buffer: ['fast', 'slow'],
|
||||
type: ['UInt8', 'UInt16LE', 'UInt16BE',
|
||||
'UInt32LE', 'UInt32BE',
|
||||
'Int8', 'Int16LE', 'Int16BE',
|
||||
'Int32LE', 'Int32BE',
|
||||
'FloatLE', 'FloatBE',
|
||||
'DoubleLE', 'DoubleBE'],
|
||||
millions: [1]
|
||||
});
|
||||
```
|
||||
The runner takes one item from each of the property array value to build a list
|
||||
of arguments to run the main function. The main function will receive the conf
|
||||
object as follows:
|
||||
|
||||
- first run:
|
||||
```js
|
||||
{ noAssert: false,
|
||||
buffer: 'fast',
|
||||
type: 'UInt8',
|
||||
millions: 1
|
||||
}
|
||||
```
|
||||
- second run:
|
||||
```js
|
||||
{
|
||||
noAssert: false,
|
||||
buffer: 'fast',
|
||||
type: 'UInt16LE',
|
||||
millions: 1
|
||||
}
|
||||
```
|
||||
...
|
||||
|
||||
In this case, the main function will run 2*2*14*1 = 56 times. The console output
|
||||
looks like the following:
|
||||
|
||||
```
|
||||
buffers//buffer-read.js
|
||||
buffers/buffer-read.js noAssert=false buffer=fast type=UInt8 millions=1: 271.83
|
||||
buffers/buffer-read.js noAssert=false buffer=fast type=UInt16LE millions=1: 239.43
|
||||
buffers/buffer-read.js noAssert=false buffer=fast type=UInt16BE millions=1: 244.57
|
||||
...
|
||||
```
|
||||
|
||||
2. Run an individual test, for example, buffer-slice.js
|
||||
|
||||
```sh
|
||||
node benchmark/buffers/buffer-read.js
|
||||
```
|
||||
The output:
|
||||
```
|
||||
buffers/buffer-read.js noAssert=false buffer=fast type=UInt8 millions=1: 246.79
|
||||
buffers/buffer-read.js noAssert=false buffer=fast type=UInt16LE millions=1: 240.11
|
||||
buffers/buffer-read.js noAssert=false buffer=fast type=UInt16BE millions=1: 245.91
|
||||
...
|
||||
```
|
||||
|
||||
## How to write a benchmark test
|
||||
|
||||
The benchmark tests are grouped by types. Each type corresponds to a subdirectory,
|
||||
such as `arrays`, `buffers`, or `fs`.
|
||||
|
||||
Let's add a benchmark test for Buffer.slice function. We first create a file
|
||||
buffers/buffer-slice.js.
|
||||
|
||||
### The code snippet
|
||||
|
||||
```js
|
||||
var common = require('../common.js'); // Load the test runner
|
||||
|
||||
var SlowBuffer = require('buffer').SlowBuffer;
|
||||
|
||||
// Create a benchmark test for function `main` and the configuration variants
|
||||
var bench = common.createBenchmark(main, {
|
||||
type: ['fast', 'slow'], // Two types of buffer
|
||||
n: [512] // Number of times (each unit is 1024) to call the slice API
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
// Read the parameters from the configuration
|
||||
var n = +conf.n;
|
||||
var b = conf.type === 'fast' ? buf : slowBuf;
|
||||
bench.start(); // Start benchmarking
|
||||
for (var i = 0; i < n * 1024; i++) {
|
||||
// Add your test here
|
||||
b.slice(10, 256);
|
||||
}
|
||||
bench.end(n); // End benchmarking
|
||||
}
|
||||
```
|
||||
@@ -1,20 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
type: 'Array Buffer Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' '),
|
||||
n: [25]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var type = conf.type;
|
||||
var clazz = global[type];
|
||||
var n = +conf.n;
|
||||
|
||||
bench.start();
|
||||
var arr = new clazz(n * 1e6);
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
for (var j = 0, k = arr.length; j < k; ++j) {
|
||||
arr[j] = (j ^ k) & 127;
|
||||
}
|
||||
}
|
||||
bench.end(n);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
type: 'Array Buffer Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' '),
|
||||
n: [25]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var type = conf.type;
|
||||
var clazz = global[type];
|
||||
var n = +conf.n;
|
||||
|
||||
bench.start();
|
||||
var arr = new clazz(n * 1e6);
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
for (var j = 0, k = arr.length; j < k; ++j) {
|
||||
arr[j] = 0.0;
|
||||
}
|
||||
}
|
||||
bench.end(n);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
type: 'Array Buffer Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' '),
|
||||
n: [25]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var type = conf.type;
|
||||
var clazz = global[type];
|
||||
var n = +conf.n;
|
||||
|
||||
bench.start();
|
||||
var arr = new clazz(n * 1e6);
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
for (var j = 0, k = arr.length; j < k; ++j) {
|
||||
arr[j] = 0;
|
||||
}
|
||||
}
|
||||
bench.end(n);
|
||||
}
|
||||
6
benchmark/buffer_creation.js
Normal file
6
benchmark/buffer_creation.js
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
for (var i = 0; i < 9e7; i++) {
|
||||
b = new Buffer(10);
|
||||
b[1] = 2
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var common = require('../common.js');
|
||||
|
||||
var bench = common.createBenchmark(main, {});
|
||||
|
||||
function main(conf) {
|
||||
var N = 64 * 1024 * 1024;
|
||||
var b = Buffer(N);
|
||||
var s = '';
|
||||
for (var i = 0; i < 256; ++i) s += String.fromCharCode(i);
|
||||
for (var i = 0; i < N; i += 256) b.write(s, i, 256, 'ascii');
|
||||
bench.start();
|
||||
for (var i = 0; i < 32; ++i) b.toString('base64');
|
||||
bench.end(64);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var common = require('../common.js');
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
size: [16, 512, 1024, 4096, 16386],
|
||||
millions: [1]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var iter = (conf.millions >>> 0) * 1e6;
|
||||
var size = (conf.size >>> 0);
|
||||
var b0 = new Buffer(size).fill('a');
|
||||
var b1 = new Buffer(size).fill('a');
|
||||
|
||||
b1[size - 1] = 'b'.charCodeAt(0);
|
||||
|
||||
bench.start();
|
||||
for (var i = 0; i < iter; i++) {
|
||||
Buffer.compare(b0, b1);
|
||||
}
|
||||
bench.end(iter / 1e6);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
SlowBuffer = require('buffer').SlowBuffer;
|
||||
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
type: ['fast', 'slow'],
|
||||
len: [10, 1024],
|
||||
n: [1024]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var len = +conf.len;
|
||||
var n = +conf.n;
|
||||
var clazz = conf.type === 'fast' ? Buffer : SlowBuffer;
|
||||
bench.start();
|
||||
for (var i = 0; i < n * 1024; i++) {
|
||||
b = new clazz(len);
|
||||
}
|
||||
bench.end(n);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
noAssert: [false, true],
|
||||
buffer: ['fast', 'slow'],
|
||||
type: ['UInt8', 'UInt16LE', 'UInt16BE',
|
||||
'UInt32LE', 'UInt32BE',
|
||||
'Int8', 'Int16LE', 'Int16BE',
|
||||
'Int32LE', 'Int32BE',
|
||||
'FloatLE', 'FloatBE',
|
||||
'DoubleLE', 'DoubleBE'],
|
||||
millions: [1]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var noAssert = conf.noAssert === 'true';
|
||||
var len = +conf.millions * 1e6;
|
||||
var clazz = conf.buf === 'fast' ? Buffer : require('buffer').SlowBuffer;
|
||||
var buff = new clazz(8);
|
||||
var fn = 'read' + conf.type;
|
||||
|
||||
buff.writeDoubleLE(0, 0, noAssert);
|
||||
var testFunction = new Function('buff', [
|
||||
"for (var i = 0; i !== " + len + "; i++) {",
|
||||
" buff." + fn + "(0, " + JSON.stringify(noAssert) + ");",
|
||||
"}"
|
||||
].join("\n"));
|
||||
bench.start();
|
||||
testFunction(buff);
|
||||
bench.end(len / 1e6);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
var SlowBuffer = require('buffer').SlowBuffer;
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
type: ['fast', 'slow'],
|
||||
n: [1024]
|
||||
});
|
||||
|
||||
var buf = new Buffer(1024);
|
||||
var slowBuf = new SlowBuffer(1024);
|
||||
|
||||
function main(conf) {
|
||||
var n = +conf.n;
|
||||
var b = conf.type === 'fast' ? buf : slowBuf;
|
||||
bench.start();
|
||||
for (var i = 0; i < n * 1024; i++) {
|
||||
b.slice(10, 256);
|
||||
}
|
||||
bench.end(n);
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
noAssert: [false, true],
|
||||
buffer: ['fast', 'slow'],
|
||||
type: ['UInt8', 'UInt16LE', 'UInt16BE',
|
||||
'UInt32LE', 'UInt32BE',
|
||||
'Int8', 'Int16LE', 'Int16BE',
|
||||
'Int32LE', 'Int32BE',
|
||||
'FloatLE', 'FloatBE',
|
||||
'DoubleLE', 'DoubleBE'],
|
||||
millions: [1]
|
||||
});
|
||||
|
||||
const INT8 = 0x7f;
|
||||
const INT16 = 0x7fff;
|
||||
const INT32 = 0x7fffffff;
|
||||
const UINT8 = (INT8 * 2) + 1;
|
||||
const UINT16 = (INT16 * 2) + 1;
|
||||
const UINT32 = INT32;
|
||||
|
||||
var mod = {
|
||||
writeInt8: INT8,
|
||||
writeInt16BE: INT16,
|
||||
writeInt16LE: INT16,
|
||||
writeInt32BE: INT32,
|
||||
writeInt32LE: INT32,
|
||||
writeUInt8: UINT8,
|
||||
writeUInt16BE: UINT16,
|
||||
writeUInt16LE: UINT16,
|
||||
writeUInt32BE: UINT32,
|
||||
writeUInt32LE: UINT32
|
||||
};
|
||||
|
||||
function main(conf) {
|
||||
var noAssert = conf.noAssert === 'true';
|
||||
var len = +conf.millions * 1e6;
|
||||
var clazz = conf.buf === 'fast' ? Buffer : require('buffer').SlowBuffer;
|
||||
var buff = new clazz(8);
|
||||
var fn = 'write' + conf.type;
|
||||
|
||||
if (fn.match(/Int/))
|
||||
benchInt(buff, fn, len, noAssert);
|
||||
else
|
||||
benchFloat(buff, fn, len, noAssert);
|
||||
}
|
||||
|
||||
function benchInt(buff, fn, len, noAssert) {
|
||||
var m = mod[fn];
|
||||
var testFunction = new Function('buff', [
|
||||
"for (var i = 0; i !== " + len + "; i++) {",
|
||||
" buff." + fn + "(i & " + m + ", 0, " + JSON.stringify(noAssert) + ");",
|
||||
"}"
|
||||
].join("\n"));
|
||||
bench.start();
|
||||
testFunction(buff);
|
||||
bench.end(len / 1e6);
|
||||
}
|
||||
|
||||
function benchFloat(buff, fn, len, noAssert) {
|
||||
var testFunction = new Function('buff', [
|
||||
"for (var i = 0; i !== " + len + "; i++) {",
|
||||
" buff." + fn + "(i, 0, " + JSON.stringify(noAssert) + ");",
|
||||
"}"
|
||||
].join("\n"));
|
||||
bench.start();
|
||||
testFunction(buff);
|
||||
bench.end(len / 1e6);
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
type: ['Uint8', 'Uint16LE', 'Uint16BE',
|
||||
'Uint32LE', 'Uint32BE',
|
||||
'Int8', 'Int16LE', 'Int16BE',
|
||||
'Int32LE', 'Int32BE',
|
||||
'Float32LE', 'Float32BE',
|
||||
'Float64LE', 'Float64BE'],
|
||||
millions: [1]
|
||||
});
|
||||
|
||||
const INT8 = 0x7f;
|
||||
const INT16 = 0x7fff;
|
||||
const INT32 = 0x7fffffff;
|
||||
const UINT8 = INT8 * 2;
|
||||
const UINT16 = INT16 * 2;
|
||||
const UINT32 = INT32 * 2;
|
||||
|
||||
var mod = {
|
||||
setInt8: INT8,
|
||||
setInt16: INT16,
|
||||
setInt32: INT32,
|
||||
setUint8: UINT8,
|
||||
setUint16: UINT16,
|
||||
setUint32: UINT32
|
||||
};
|
||||
|
||||
function main(conf) {
|
||||
var len = +conf.millions * 1e6;
|
||||
var ab = new ArrayBuffer(8);
|
||||
var dv = new DataView(ab, 0, 8);
|
||||
var le = /LE$/.test(conf.type);
|
||||
var fn = 'set' + conf.type.replace(/[LB]E$/, '');
|
||||
|
||||
if (/int/i.test(fn))
|
||||
benchInt(dv, fn, len, le);
|
||||
else
|
||||
benchFloat(dv, fn, len, le);
|
||||
}
|
||||
|
||||
function benchInt(dv, fn, len, le) {
|
||||
var m = mod[fn];
|
||||
bench.start();
|
||||
for (var i = 0; i < len; i++) {
|
||||
dv[fn](0, i % m, le);
|
||||
}
|
||||
bench.end(len / 1e6);
|
||||
}
|
||||
|
||||
function benchFloat(dv, fn, len, le) {
|
||||
bench.start();
|
||||
for (var i = 0; i < len; i++) {
|
||||
dv[fn](0, i * 0.1, le);
|
||||
}
|
||||
bench.end(len / 1e6);
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
var assert = require('assert');
|
||||
var path = require('path');
|
||||
var silent = +process.env.NODE_BENCH_SILENT;
|
||||
|
||||
exports.PORT = process.env.PORT || 12346;
|
||||
|
||||
// If this is the main module, then run the benchmarks
|
||||
if (module === require.main) {
|
||||
var type = process.argv[2];
|
||||
if (!type) {
|
||||
console.error('usage:\n ./node benchmark/common.js <type>');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var fs = require('fs');
|
||||
var dir = path.join(__dirname, type);
|
||||
var tests = fs.readdirSync(dir);
|
||||
var spawn = require('child_process').spawn;
|
||||
|
||||
runBenchmarks();
|
||||
}
|
||||
|
||||
function runBenchmarks() {
|
||||
var test = tests.shift();
|
||||
if (!test)
|
||||
return;
|
||||
|
||||
if (test.match(/^[\._]/))
|
||||
return process.nextTick(runBenchmarks);
|
||||
|
||||
console.error(type + '/' + test);
|
||||
test = path.resolve(dir, test);
|
||||
|
||||
var a = (process.execArgv || []).concat(test);
|
||||
var child = spawn(process.execPath, a, { stdio: 'inherit' });
|
||||
child.on('close', function(code) {
|
||||
if (code)
|
||||
process.exit(code);
|
||||
else {
|
||||
console.log('');
|
||||
runBenchmarks();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
exports.createBenchmark = function(fn, options) {
|
||||
return new Benchmark(fn, options);
|
||||
};
|
||||
|
||||
function Benchmark(fn, options) {
|
||||
this.fn = fn;
|
||||
this.options = options;
|
||||
this.config = parseOpts(options);
|
||||
this._name = require.main.filename.split(/benchmark[\/\\]/).pop();
|
||||
this._start = [0,0];
|
||||
this._started = false;
|
||||
var self = this;
|
||||
process.nextTick(function() {
|
||||
self._run();
|
||||
});
|
||||
}
|
||||
|
||||
// benchmark an http server.
|
||||
Benchmark.prototype.http = function(p, args, cb) {
|
||||
var self = this;
|
||||
var wrk = path.resolve(__dirname, '..', 'tools', 'wrk', 'wrk');
|
||||
var regexp = /Requests\/sec:[ \t]+([0-9\.]+)/;
|
||||
var spawn = require('child_process').spawn;
|
||||
var url = 'http://127.0.0.1:' + exports.PORT + p;
|
||||
|
||||
args = args.concat(url);
|
||||
|
||||
var out = '';
|
||||
var child = spawn(wrk, args);
|
||||
|
||||
child.stdout.setEncoding('utf8');
|
||||
|
||||
child.stdout.on('data', function(chunk) {
|
||||
out += chunk;
|
||||
});
|
||||
|
||||
child.on('close', function(code) {
|
||||
if (cb)
|
||||
cb(code);
|
||||
|
||||
if (code) {
|
||||
console.error('wrk failed with ' + code);
|
||||
process.exit(code)
|
||||
}
|
||||
var m = out.match(regexp);
|
||||
var qps = m && +m[1];
|
||||
if (!qps) {
|
||||
console.error('%j', out);
|
||||
console.error('wrk produced strange output');
|
||||
process.exit(1);
|
||||
}
|
||||
self.report(+qps);
|
||||
});
|
||||
};
|
||||
|
||||
Benchmark.prototype._run = function() {
|
||||
if (this.config)
|
||||
return this.fn(this.config);
|
||||
|
||||
// one more more options weren't set.
|
||||
// run with all combinations
|
||||
var main = require.main.filename;
|
||||
var settings = [];
|
||||
var queueLen = 1;
|
||||
var options = this.options;
|
||||
|
||||
var queue = Object.keys(options).reduce(function(set, key) {
|
||||
var vals = options[key];
|
||||
assert(Array.isArray(vals));
|
||||
|
||||
// match each item in the set with each item in the list
|
||||
var newSet = new Array(set.length * vals.length);
|
||||
var j = 0;
|
||||
set.forEach(function(s) {
|
||||
vals.forEach(function(val) {
|
||||
newSet[j++] = s.concat(key + '=' + val);
|
||||
});
|
||||
});
|
||||
return newSet;
|
||||
}, [[main]]);
|
||||
|
||||
var spawn = require('child_process').spawn;
|
||||
var node = process.execPath;
|
||||
var i = 0;
|
||||
function run() {
|
||||
var argv = queue[i++];
|
||||
if (!argv)
|
||||
return;
|
||||
var child = spawn(node, argv, { stdio: 'inherit' });
|
||||
child.on('close', function(code, signal) {
|
||||
if (code)
|
||||
console.error('child process exited with code ' + code);
|
||||
else
|
||||
run();
|
||||
});
|
||||
}
|
||||
run();
|
||||
};
|
||||
|
||||
function parseOpts(options) {
|
||||
// verify that there's an option provided for each of the options
|
||||
// if they're not *all* specified, then we return null.
|
||||
var keys = Object.keys(options);
|
||||
var num = keys.length;
|
||||
var conf = {};
|
||||
for (var i = 2; i < process.argv.length; i++) {
|
||||
var m = process.argv[i].match(/^(.+)=(.+)$/);
|
||||
if (!m || !m[1] || !m[2] || !options[m[1]])
|
||||
return null;
|
||||
else {
|
||||
conf[m[1]] = isFinite(m[2]) ? +m[2] : m[2]
|
||||
num--;
|
||||
}
|
||||
}
|
||||
// still go ahead and set whatever WAS set, if it was.
|
||||
if (num !== 0) {
|
||||
Object.keys(conf).forEach(function(k) {
|
||||
options[k] = [conf[k]];
|
||||
});
|
||||
}
|
||||
return num === 0 ? conf : null;
|
||||
};
|
||||
|
||||
Benchmark.prototype.start = function() {
|
||||
if (this._started)
|
||||
throw new Error('Called start more than once in a single benchmark');
|
||||
this._started = true;
|
||||
this._start = process.hrtime();
|
||||
};
|
||||
|
||||
Benchmark.prototype.end = function(operations) {
|
||||
var elapsed = process.hrtime(this._start);
|
||||
if (!this._started)
|
||||
throw new Error('called end without start');
|
||||
if (typeof operations !== 'number')
|
||||
throw new Error('called end() without specifying operation count');
|
||||
var time = elapsed[0] + elapsed[1]/1e9;
|
||||
var rate = operations/time;
|
||||
this.report(rate);
|
||||
};
|
||||
|
||||
Benchmark.prototype.report = function(value) {
|
||||
var heading = this.getHeading();
|
||||
if (!silent)
|
||||
console.log('%s: %s', heading, value.toPrecision(5));
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
Benchmark.prototype.getHeading = function() {
|
||||
var conf = this.config;
|
||||
return this._name + ' ' + Object.keys(conf).map(function(key) {
|
||||
return key + '=' + conf[key];
|
||||
}).join(' ');
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
var usage = 'node benchmark/compare.js ' +
|
||||
'<node-binary1> <node-binary2> ' +
|
||||
'[--html] [--red|-r] [--green|-g]';
|
||||
|
||||
var show = 'both';
|
||||
var nodes = [];
|
||||
var html = false;
|
||||
|
||||
for (var i = 2; i < process.argv.length; i++) {
|
||||
var arg = process.argv[i];
|
||||
switch (arg) {
|
||||
case '--red': case '-r':
|
||||
show = show === 'green' ? 'both' : 'red';
|
||||
break;
|
||||
case '--green': case '-g':
|
||||
show = show === 'red' ? 'both' : 'green';
|
||||
break;
|
||||
case '--html':
|
||||
html = true;
|
||||
break;
|
||||
case '-h': case '-?': case '--help':
|
||||
console.log(usage);
|
||||
process.exit(0);
|
||||
default:
|
||||
nodes.push(arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!html) {
|
||||
var start = '';
|
||||
var green = '\033[1;32m';
|
||||
var red = '\033[1;31m';
|
||||
var reset = '\033[m';
|
||||
var end = '';
|
||||
} else {
|
||||
var start = '<pre style="background-color:#333;color:#eee">';
|
||||
var green = '<span style="background-color:#0f0;color:#000">';
|
||||
var red = '<span style="background-color:#f00;color:#fff">';
|
||||
var reset = '</span>';
|
||||
var end = '</pre>';
|
||||
}
|
||||
|
||||
var runBench = process.env.NODE_BENCH || 'bench';
|
||||
|
||||
if (nodes.length !== 2)
|
||||
return console.error('usage:\n %s', usage);
|
||||
|
||||
var spawn = require('child_process').spawn;
|
||||
var results = {};
|
||||
var toggle = 1;
|
||||
var r = (+process.env.NODE_BENCH_RUNS || 1) * 2;
|
||||
|
||||
run();
|
||||
function run() {
|
||||
if (--r < 0)
|
||||
return compare();
|
||||
toggle = ++toggle % 2;
|
||||
|
||||
var node = nodes[toggle];
|
||||
console.error('running %s', node);
|
||||
var env = {};
|
||||
for (var i in process.env)
|
||||
env[i] = process.env[i];
|
||||
env.NODE = node;
|
||||
|
||||
var out = '';
|
||||
var child = spawn('make', [runBench], { env: env });
|
||||
child.stdout.setEncoding('utf8');
|
||||
child.stdout.on('data', function(c) {
|
||||
out += c;
|
||||
});
|
||||
|
||||
child.stderr.pipe(process.stderr);
|
||||
|
||||
child.on('close', function(code) {
|
||||
if (code) {
|
||||
console.error('%s exited with code=%d', node, code);
|
||||
process.exit(code);
|
||||
} else {
|
||||
out.trim().split(/\r?\n/).forEach(function(line) {
|
||||
line = line.trim();
|
||||
if (!line)
|
||||
return;
|
||||
|
||||
var s = line.split(':');
|
||||
var num = +s.pop();
|
||||
if (!num && num !== 0)
|
||||
return;
|
||||
|
||||
line = s.join(':');
|
||||
var res = results[line] = results[line] || {};
|
||||
res[node] = res[node] || [];
|
||||
res[node].push(num);
|
||||
});
|
||||
|
||||
run();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function compare() {
|
||||
// each result is an object with {"foo.js arg=bar":12345,...}
|
||||
// compare each thing, and show which node did the best.
|
||||
// node[0] is shown in green, node[1] shown in red.
|
||||
var maxLen = -Infinity;
|
||||
var util = require('util');
|
||||
console.log(start);
|
||||
|
||||
Object.keys(results).map(function(bench) {
|
||||
var res = results[bench];
|
||||
var n0 = avg(res[nodes[0]]);
|
||||
var n1 = avg(res[nodes[1]]);
|
||||
|
||||
var pct = ((n0 - n1) / n1 * 100).toFixed(2);
|
||||
|
||||
var g = n0 > n1 ? green : '';
|
||||
var r = n0 > n1 ? '' : red;
|
||||
var c = r || g;
|
||||
|
||||
if (show === 'green' && !g || show === 'red' && !r)
|
||||
return;
|
||||
|
||||
var r0 = util.format('%s%s: %d%s', g, nodes[0], n0.toPrecision(5), g ? reset : '');
|
||||
var r1 = util.format('%s%s: %d%s', r, nodes[1], n1.toPrecision(5), r ? reset : '');
|
||||
var pct = c + pct + '%' + reset;
|
||||
var l = util.format('%s: %s %s', bench, r0, r1);
|
||||
maxLen = Math.max(l.length + pct.length, maxLen);
|
||||
return [l, pct];
|
||||
}).filter(function(l) {
|
||||
return l;
|
||||
}).forEach(function(line) {
|
||||
var l = line[0];
|
||||
var pct = line[1];
|
||||
var dotLen = maxLen - l.length - pct.length + 2;
|
||||
var dots = ' ' + new Array(Math.max(0, dotLen)).join('.') + ' ';
|
||||
console.log(l + dots + pct);
|
||||
});
|
||||
console.log(end);
|
||||
}
|
||||
|
||||
function avg(list) {
|
||||
if (list.length >= 3) {
|
||||
list = list.sort();
|
||||
var q = Math.floor(list.length / 4) || 1;
|
||||
list = list.slice(q, -q);
|
||||
}
|
||||
return list.reduce(function(a, b) {
|
||||
return a + b;
|
||||
}, 0) / list.length;
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
writes: [500],
|
||||
cipher: [ 'AES192', 'AES256' ],
|
||||
type: ['asc', 'utf', 'buf'],
|
||||
len: [2, 1024, 102400, 1024 * 1024],
|
||||
api: ['legacy', 'stream']
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var api = conf.api;
|
||||
if (api === 'stream' && process.version.match(/^v0\.[0-8]\./)) {
|
||||
console.error('Crypto streams not available until v0.10');
|
||||
// use the legacy, just so that we can compare them.
|
||||
api = 'legacy';
|
||||
}
|
||||
|
||||
var crypto = require('crypto');
|
||||
var assert = require('assert');
|
||||
var alice = crypto.getDiffieHellman('modp5');
|
||||
var bob = crypto.getDiffieHellman('modp5');
|
||||
|
||||
alice.generateKeys();
|
||||
bob.generateKeys();
|
||||
|
||||
|
||||
var pubEnc = /^v0\.[0-8]/.test(process.version) ? 'binary' : null;
|
||||
var alice_secret = alice.computeSecret(bob.getPublicKey(), pubEnc, 'hex');
|
||||
var bob_secret = bob.computeSecret(alice.getPublicKey(), pubEnc, 'hex');
|
||||
|
||||
// alice_secret and bob_secret should be the same
|
||||
assert(alice_secret == bob_secret);
|
||||
|
||||
var alice_cipher = crypto.createCipher(conf.cipher, alice_secret);
|
||||
var bob_cipher = crypto.createDecipher(conf.cipher, bob_secret);
|
||||
|
||||
var message;
|
||||
var encoding;
|
||||
switch (conf.type) {
|
||||
case 'asc':
|
||||
message = new Array(conf.len + 1).join('a');
|
||||
encoding = 'ascii';
|
||||
break;
|
||||
case 'utf':
|
||||
message = new Array(conf.len / 2 + 1).join('ü');
|
||||
encoding = 'utf8';
|
||||
break;
|
||||
case 'buf':
|
||||
message = new Buffer(conf.len);
|
||||
message.fill('b');
|
||||
break;
|
||||
default:
|
||||
throw new Error('unknown message type: ' + conf.type);
|
||||
}
|
||||
|
||||
var fn = api === 'stream' ? streamWrite : legacyWrite;
|
||||
|
||||
// write data as fast as possible to alice, and have bob decrypt.
|
||||
// use old API for comparison to v0.8
|
||||
bench.start();
|
||||
fn(alice_cipher, bob_cipher, message, encoding, conf.writes);
|
||||
}
|
||||
|
||||
function streamWrite(alice, bob, message, encoding, writes) {
|
||||
var written = 0;
|
||||
bob.on('data', function(c) {
|
||||
written += c.length;
|
||||
});
|
||||
|
||||
bob.on('end', function() {
|
||||
// Gbits
|
||||
var bits = written * 8;
|
||||
var gbits = bits / (1024 * 1024 * 1024);
|
||||
bench.end(gbits);
|
||||
});
|
||||
|
||||
alice.pipe(bob);
|
||||
|
||||
while (writes-- > 0)
|
||||
alice.write(message, encoding);
|
||||
|
||||
alice.end();
|
||||
}
|
||||
|
||||
function legacyWrite(alice, bob, message, encoding, writes) {
|
||||
var written = 0;
|
||||
for (var i = 0; i < writes; i++) {
|
||||
var enc = alice.update(message, encoding);
|
||||
var dec = bob.update(enc);
|
||||
written += dec.length;
|
||||
}
|
||||
var enc = alice.final();
|
||||
var dec = bob.update(enc);
|
||||
written += dec.length;
|
||||
dec = bob.final();
|
||||
written += dec.length;
|
||||
var bits = written * 8;
|
||||
var gbits = written / (1024 * 1024 * 1024);
|
||||
bench.end(gbits);
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
// throughput benchmark
|
||||
// creates a single hasher, then pushes a bunch of data through it
|
||||
var common = require('../common.js');
|
||||
var crypto = require('crypto');
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
writes: [500],
|
||||
algo: [ 'sha256', 'md5' ],
|
||||
type: ['asc', 'utf', 'buf'],
|
||||
out: ['hex', 'binary', 'buffer'],
|
||||
len: [2, 1024, 102400, 1024 * 1024],
|
||||
api: ['legacy', 'stream']
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var api = conf.api;
|
||||
if (api === 'stream' && process.version.match(/^v0\.[0-8]\./)) {
|
||||
console.error('Crypto streams not available until v0.10');
|
||||
// use the legacy, just so that we can compare them.
|
||||
api = 'legacy';
|
||||
}
|
||||
|
||||
var crypto = require('crypto');
|
||||
var assert = require('assert');
|
||||
|
||||
var message;
|
||||
var encoding;
|
||||
switch (conf.type) {
|
||||
case 'asc':
|
||||
message = new Array(conf.len + 1).join('a');
|
||||
encoding = 'ascii';
|
||||
break;
|
||||
case 'utf':
|
||||
message = new Array(conf.len / 2 + 1).join('ü');
|
||||
encoding = 'utf8';
|
||||
break;
|
||||
case 'buf':
|
||||
message = new Buffer(conf.len);
|
||||
message.fill('b');
|
||||
break;
|
||||
default:
|
||||
throw new Error('unknown message type: ' + conf.type);
|
||||
}
|
||||
|
||||
var fn = api === 'stream' ? streamWrite : legacyWrite;
|
||||
|
||||
bench.start();
|
||||
fn(conf.algo, message, encoding, conf.writes, conf.len, conf.out);
|
||||
}
|
||||
|
||||
function legacyWrite(algo, message, encoding, writes, len, outEnc) {
|
||||
var written = writes * len;
|
||||
var bits = written * 8;
|
||||
var gbits = bits / (1024 * 1024 * 1024);
|
||||
|
||||
while (writes-- > 0) {
|
||||
var h = crypto.createHash(algo);
|
||||
h.update(message, encoding);
|
||||
var res = h.digest(outEnc);
|
||||
|
||||
// include buffer creation costs for older versions
|
||||
if (outEnc === 'buffer' && typeof res === 'string')
|
||||
res = new Buffer(res, 'binary');
|
||||
}
|
||||
|
||||
bench.end(gbits);
|
||||
}
|
||||
|
||||
function streamWrite(algo, message, encoding, writes, len, outEnc) {
|
||||
var written = writes * len;
|
||||
var bits = written * 8;
|
||||
var gbits = bits / (1024 * 1024 * 1024);
|
||||
|
||||
while (writes-- > 0) {
|
||||
var h = crypto.createHash(algo);
|
||||
|
||||
if (outEnc !== 'buffer')
|
||||
h.setEncoding(outEnc);
|
||||
|
||||
h.write(message, encoding);
|
||||
h.end();
|
||||
h.read();
|
||||
}
|
||||
|
||||
bench.end(gbits);
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
// throughput benchmark
|
||||
// creates a single hasher, then pushes a bunch of data through it
|
||||
var common = require('../common.js');
|
||||
var crypto = require('crypto');
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
writes: [500],
|
||||
algo: [ 'sha256', 'md5' ],
|
||||
type: ['asc', 'utf', 'buf'],
|
||||
len: [2, 1024, 102400, 1024 * 1024],
|
||||
api: ['legacy', 'stream']
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var api = conf.api;
|
||||
if (api === 'stream' && process.version.match(/^v0\.[0-8]\./)) {
|
||||
console.error('Crypto streams not available until v0.10');
|
||||
// use the legacy, just so that we can compare them.
|
||||
api = 'legacy';
|
||||
}
|
||||
|
||||
var crypto = require('crypto');
|
||||
var assert = require('assert');
|
||||
|
||||
var message;
|
||||
var encoding;
|
||||
switch (conf.type) {
|
||||
case 'asc':
|
||||
message = new Array(conf.len + 1).join('a');
|
||||
encoding = 'ascii';
|
||||
break;
|
||||
case 'utf':
|
||||
message = new Array(conf.len / 2 + 1).join('ü');
|
||||
encoding = 'utf8';
|
||||
break;
|
||||
case 'buf':
|
||||
message = new Buffer(conf.len);
|
||||
message.fill('b');
|
||||
break;
|
||||
default:
|
||||
throw new Error('unknown message type: ' + conf.type);
|
||||
}
|
||||
|
||||
var fn = api === 'stream' ? streamWrite : legacyWrite;
|
||||
|
||||
bench.start();
|
||||
fn(conf.algo, message, encoding, conf.writes, conf.len);
|
||||
}
|
||||
|
||||
function legacyWrite(algo, message, encoding, writes, len) {
|
||||
var written = writes * len;
|
||||
var bits = written * 8;
|
||||
var gbits = bits / (1024 * 1024 * 1024);
|
||||
var h = crypto.createHash(algo);
|
||||
|
||||
while (writes-- > 0)
|
||||
h.update(message, encoding);
|
||||
|
||||
h.digest();
|
||||
|
||||
bench.end(gbits);
|
||||
}
|
||||
|
||||
function streamWrite(algo, message, encoding, writes, len) {
|
||||
var written = writes * len;
|
||||
var bits = written * 8;
|
||||
var gbits = bits / (1024 * 1024 * 1024);
|
||||
var h = crypto.createHash(algo);
|
||||
|
||||
while (writes-- > 0)
|
||||
h.write(message, encoding);
|
||||
|
||||
h.end();
|
||||
h.read();
|
||||
|
||||
bench.end(gbits);
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
|
||||
// If there are no args, then this is the root. Run all the benchmarks!
|
||||
if (!process.argv[2])
|
||||
parent();
|
||||
else
|
||||
runTest(+process.argv[2], +process.argv[3], process.argv[4]);
|
||||
|
||||
function parent() {
|
||||
var types = [ 'string', 'buffer' ];
|
||||
var durs = [ 1, 5 ];
|
||||
var sizes = [ 1, 10, 100, 2048, 10240 ];
|
||||
var queue = [];
|
||||
types.forEach(function(t) {
|
||||
durs.forEach(function(d) {
|
||||
sizes.forEach(function(s) {
|
||||
queue.push([__filename, d, s, t]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var spawn = require('child_process').spawn;
|
||||
var node = process.execPath;
|
||||
|
||||
run();
|
||||
|
||||
function run() {
|
||||
var args = queue.shift();
|
||||
if (!args)
|
||||
return;
|
||||
var child = spawn(node, args, { stdio: 'inherit' });
|
||||
child.on('close', function(code, signal) {
|
||||
if (code)
|
||||
throw new Error('Benchmark failed: ' + args.slice(1));
|
||||
run();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function runTest(dur, size, type) {
|
||||
if (type !== 'string')
|
||||
type = 'buffer';
|
||||
switch (type) {
|
||||
case 'string':
|
||||
var chunk = new Array(size + 1).join('a');
|
||||
break;
|
||||
case 'buffer':
|
||||
var chunk = new Buffer(size);
|
||||
chunk.fill('a');
|
||||
break;
|
||||
}
|
||||
|
||||
var writes = 0;
|
||||
var fs = require('fs');
|
||||
try { fs.unlinkSync('write_stream_throughput'); } catch (e) {}
|
||||
|
||||
var start
|
||||
var end;
|
||||
function done() {
|
||||
var time = end[0] + end[1]/1E9;
|
||||
var written = fs.statSync('write_stream_throughput').size / 1024;
|
||||
var rate = (written / time).toFixed(2);
|
||||
console.log('fs_write_stream_dur_%d_size_%d_type_%s: %d',
|
||||
dur, size, type, rate);
|
||||
|
||||
try { fs.unlinkSync('write_stream_throughput'); } catch (e) {}
|
||||
}
|
||||
|
||||
var f = require('fs').createWriteStream('write_stream_throughput');
|
||||
f.on('drain', write);
|
||||
f.on('open', write);
|
||||
f.on('close', done);
|
||||
|
||||
// streams2 fs.WriteStreams will let you send a lot of writes into the
|
||||
// buffer before returning false, so capture the *actual* end time when
|
||||
// all the bytes have been written to the disk, indicated by 'finish'
|
||||
f.on('finish', function() {
|
||||
end = process.hrtime(start);
|
||||
});
|
||||
|
||||
var ending = false;
|
||||
function write() {
|
||||
// don't try to write after we end, even if a 'drain' event comes.
|
||||
// v0.8 streams are so sloppy!
|
||||
if (ending)
|
||||
return;
|
||||
|
||||
start = start || process.hrtime();
|
||||
while (false !== f.write(chunk));
|
||||
end = process.hrtime(start);
|
||||
|
||||
if (end[0] >= dur) {
|
||||
ending = true;
|
||||
f.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
// test the throughput of the fs.WriteStream class.
|
||||
|
||||
var path = require('path');
|
||||
var common = require('../common.js');
|
||||
var filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
|
||||
var fs = require('fs');
|
||||
var filesize = 1000 * 1024 * 1024;
|
||||
var assert = require('assert');
|
||||
|
||||
var type, encoding, size;
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
type: ['buf', 'asc', 'utf'],
|
||||
size: [1024, 4096, 65535, 1024*1024]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
type = conf.type;
|
||||
size = +conf.size;
|
||||
|
||||
switch (type) {
|
||||
case 'buf':
|
||||
encoding = null;
|
||||
break;
|
||||
case 'asc':
|
||||
encoding = 'ascii';
|
||||
break;
|
||||
case 'utf':
|
||||
encoding = 'utf8';
|
||||
break;
|
||||
default:
|
||||
throw new Error('invalid type');
|
||||
}
|
||||
|
||||
makeFile(runTest);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
assert(fs.statSync(filename).size === filesize);
|
||||
var rs = fs.createReadStream(filename, {
|
||||
highWaterMark: size,
|
||||
encoding: encoding
|
||||
});
|
||||
|
||||
rs.on('open', function() {
|
||||
bench.start();
|
||||
});
|
||||
|
||||
var bytes = 0;
|
||||
rs.on('data', function(chunk) {
|
||||
bytes += chunk.length;
|
||||
});
|
||||
|
||||
rs.on('end', function() {
|
||||
try { fs.unlinkSync(filename); } catch (e) {}
|
||||
// MB/sec
|
||||
bench.end(bytes / (1024 * 1024));
|
||||
});
|
||||
}
|
||||
|
||||
function makeFile() {
|
||||
var buf = new Buffer(filesize / 1024);
|
||||
if (encoding === 'utf8') {
|
||||
// ü
|
||||
for (var i = 0; i < buf.length; i++) {
|
||||
buf[i] = i % 2 === 0 ? 0xC3 : 0xBC;
|
||||
}
|
||||
} else if (encoding === 'ascii') {
|
||||
buf.fill('a');
|
||||
} else {
|
||||
buf.fill('x');
|
||||
}
|
||||
|
||||
try { fs.unlinkSync(filename); } catch (e) {}
|
||||
var w = 1024;
|
||||
var ws = fs.createWriteStream(filename);
|
||||
ws.on('close', runTest);
|
||||
ws.on('drain', write);
|
||||
write();
|
||||
function write() {
|
||||
do {
|
||||
w--;
|
||||
} while (false !== ws.write(buf) && w > 0);
|
||||
if (w === 0)
|
||||
ws.end();
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
// Call fs.readFile over and over again really fast.
|
||||
// Then see how many times it got called.
|
||||
// Yes, this is a silly benchmark. Most benchmarks are silly.
|
||||
|
||||
var path = require('path');
|
||||
var common = require('../common.js');
|
||||
var filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
|
||||
var fs = require('fs');
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
dur: [5],
|
||||
len: [1024, 16 * 1024 * 1024],
|
||||
concurrent: [1, 10]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var len = +conf.len;
|
||||
try { fs.unlinkSync(filename); } catch (e) {}
|
||||
var data = new Buffer(len);
|
||||
data.fill('x');
|
||||
fs.writeFileSync(filename, data);
|
||||
data = null;
|
||||
|
||||
var reads = 0;
|
||||
bench.start();
|
||||
setTimeout(function() {
|
||||
bench.end(reads);
|
||||
try { fs.unlinkSync(filename); } catch (e) {}
|
||||
}, +conf.dur * 1000);
|
||||
|
||||
function read() {
|
||||
fs.readFile(filename, afterRead);
|
||||
}
|
||||
|
||||
function afterRead(er, data) {
|
||||
if (er)
|
||||
throw er;
|
||||
|
||||
if (data.length !== len)
|
||||
throw new Error('wrong number of bytes returned');
|
||||
|
||||
reads++;
|
||||
read();
|
||||
}
|
||||
|
||||
var cur = +conf.concurrent;
|
||||
while (cur--) read();
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
// test the throughput of the fs.WriteStream class.
|
||||
|
||||
var path = require('path');
|
||||
var common = require('../common.js');
|
||||
var filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
|
||||
var fs = require('fs');
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
dur: [5],
|
||||
type: ['buf', 'asc', 'utf'],
|
||||
size: [2, 1024, 65535, 1024 * 1024]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var dur = +conf.dur;
|
||||
var type = conf.type;
|
||||
var size = +conf.size;
|
||||
var encoding;
|
||||
|
||||
var chunk;
|
||||
switch (type) {
|
||||
case 'buf':
|
||||
chunk = new Buffer(size);
|
||||
chunk.fill('b');
|
||||
break;
|
||||
case 'asc':
|
||||
chunk = new Array(size + 1).join('a');
|
||||
encoding = 'ascii';
|
||||
break;
|
||||
case 'utf':
|
||||
chunk = new Array(Math.ceil(size/2) + 1).join('ü');
|
||||
encoding = 'utf8';
|
||||
break;
|
||||
default:
|
||||
throw new Error('invalid type');
|
||||
}
|
||||
|
||||
try { fs.unlinkSync(filename); } catch (e) {}
|
||||
|
||||
var started = false;
|
||||
var ending = false;
|
||||
var ended = false;
|
||||
setTimeout(function() {
|
||||
ending = true;
|
||||
f.end();
|
||||
}, dur * 1000);
|
||||
|
||||
var f = fs.createWriteStream(filename);
|
||||
f.on('drain', write);
|
||||
f.on('open', write);
|
||||
f.on('close', done);
|
||||
f.on('finish', function() {
|
||||
ended = true;
|
||||
var written = fs.statSync(filename).size / 1024;
|
||||
try { fs.unlinkSync(filename); } catch (e) {}
|
||||
bench.end(written / 1024);
|
||||
});
|
||||
|
||||
|
||||
function write() {
|
||||
// don't try to write after we end, even if a 'drain' event comes.
|
||||
// v0.8 streams are so sloppy!
|
||||
if (ending)
|
||||
return;
|
||||
|
||||
if (!started) {
|
||||
started = true;
|
||||
bench.start();
|
||||
}
|
||||
|
||||
while (false !== f.write(chunk, encoding));
|
||||
}
|
||||
|
||||
function done() {
|
||||
if (!ended)
|
||||
f.emit('finish');
|
||||
}
|
||||
}
|
||||
35
benchmark/function_call/bench.js
Normal file
35
benchmark/function_call/bench.js
Normal file
@@ -0,0 +1,35 @@
|
||||
var binding = require('./build/default/binding');
|
||||
|
||||
c = 0
|
||||
|
||||
function js() {
|
||||
return c++; //(new Date()).getTime();
|
||||
}
|
||||
|
||||
var cxx = binding.hello;
|
||||
|
||||
var i, N = 100000000;
|
||||
|
||||
console.log(js());
|
||||
console.log(cxx());
|
||||
|
||||
|
||||
|
||||
var start = new Date();
|
||||
for (i = 0; i < N; i++) {
|
||||
js();
|
||||
}
|
||||
var jsDiff = new Date() - start;
|
||||
console.log(N +" JS function calls: " + jsDiff);
|
||||
|
||||
|
||||
var start = new Date();
|
||||
for (i = 0; i < N; i++) {
|
||||
cxx();
|
||||
}
|
||||
var cxxDiff = new Date() - start;
|
||||
console.log(N +" C++ function calls: " + cxxDiff);
|
||||
|
||||
console.log("\nJS speedup " + (cxxDiff / jsDiff));
|
||||
|
||||
|
||||
19
benchmark/function_call/binding.cc
Normal file
19
benchmark/function_call/binding.cc
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <v8.h>
|
||||
#include <node.h>
|
||||
#include <time.h>
|
||||
|
||||
using namespace v8;
|
||||
|
||||
static int c = 0;
|
||||
|
||||
static Handle<Value> Hello(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
//time_t tv = time(NULL);
|
||||
return scope.Close(Integer::New(c++));
|
||||
}
|
||||
|
||||
extern "C" void init (Handle<Object> target) {
|
||||
HandleScope scope;
|
||||
//target->Set(String::New("hello"), String::New("World"));
|
||||
NODE_SET_METHOD(target, "hello", Hello);
|
||||
}
|
||||
15
benchmark/function_call/wscript
Normal file
15
benchmark/function_call/wscript
Normal file
@@ -0,0 +1,15 @@
|
||||
srcdir = '.'
|
||||
blddir = 'build'
|
||||
VERSION = '0.0.1'
|
||||
|
||||
def set_options(opt):
|
||||
opt.tool_options('compiler_cxx')
|
||||
|
||||
def configure(conf):
|
||||
conf.check_tool('compiler_cxx')
|
||||
conf.check_tool('node_addon')
|
||||
|
||||
def build(bld):
|
||||
obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
|
||||
obj.target = 'binding'
|
||||
obj.source = 'binding.cc'
|
||||
@@ -1,116 +0,0 @@
|
||||
#!/bin/bash
|
||||
cd "$(dirname "$(dirname $0)")"
|
||||
|
||||
node=${NODE:-./node}
|
||||
|
||||
name=${NAME:-stacks}
|
||||
|
||||
if type sysctl &>/dev/null; then
|
||||
# darwin and linux
|
||||
sudo sysctl -w net.inet.ip.portrange.first=12000
|
||||
sudo sysctl -w net.inet.tcp.msl=1000
|
||||
sudo sysctl -w kern.maxfiles=1000000 kern.maxfilesperproc=1000000
|
||||
elif type /usr/sbin/ndd &>/dev/null; then
|
||||
# sunos
|
||||
/usr/sbin/ndd -set /dev/tcp tcp_smallest_anon_port 12000
|
||||
/usr/sbin/ndd -set /dev/tcp tcp_largest_anon_port 65535
|
||||
/usr/sbin/ndd -set /dev/tcp tcp_max_buf 2097152
|
||||
/usr/sbin/ndd -set /dev/tcp tcp_xmit_hiwat 1048576
|
||||
/usr/sbin/ndd -set /dev/tcp tcp_recv_hiwat 1048576
|
||||
fi
|
||||
|
||||
ulimit -n 100000
|
||||
$node benchmark/http_simple.js &
|
||||
nodepid=$!
|
||||
echo "node pid = $nodepid"
|
||||
sleep 1
|
||||
|
||||
# has to stay alive until dtrace exits
|
||||
dtrace -n 'profile-97/pid == '$nodepid' && arg1/{ @[jstack(150, 8000)] = count(); } tick-60s { exit(0); }' \
|
||||
| grep -v _ZN2v88internalL21Builtin_HandleApiCallENS0_12_GLOBAL__N_116BuiltinA \
|
||||
> "$name".src &
|
||||
|
||||
dtracepid=$!
|
||||
|
||||
echo "dtrace pid = $dtracepid"
|
||||
|
||||
sleep 1
|
||||
|
||||
test () {
|
||||
c=$1
|
||||
t=$2
|
||||
l=$3
|
||||
k=$4
|
||||
ab $k -t 10 -c $c http://127.0.0.1:8000/$t/$l \
|
||||
2>&1 | grep Req
|
||||
}
|
||||
|
||||
#test 100 bytes 1024
|
||||
#test 10 bytes 100 -k
|
||||
#test 100 bytes 1024 -k
|
||||
#test 100 bytes 1024 -k
|
||||
#test 100 bytes 1024 -k
|
||||
|
||||
echo 'Keep going until dtrace stops listening...'
|
||||
while pargs $dtracepid &>/dev/null; do
|
||||
test 100 bytes ${LENGTH:-1} -k
|
||||
done
|
||||
|
||||
kill $nodepid
|
||||
|
||||
echo 'Turn the stacks into a svg'
|
||||
stackvis dtrace flamegraph-svg < "$name".src > "$name".raw.svg
|
||||
|
||||
echo 'Prune tiny stacks out of the graph'
|
||||
node -e '
|
||||
var infile = process.argv[1];
|
||||
var outfile = process.argv[2];
|
||||
var output = "";
|
||||
var fs = require("fs");
|
||||
var input = fs.readFileSync(infile, "utf8");
|
||||
|
||||
input = input.split("id=\"details\" > </text>");
|
||||
var head = input.shift() + "id=\"details\" > </text>";
|
||||
input = input.join("id=\"details\" > </text>");
|
||||
|
||||
var tail = "</svg>";
|
||||
input = input.split("</svg>")[0];
|
||||
|
||||
var minyKept = Infinity;
|
||||
var minyOverall = Infinity;
|
||||
var rects = input.trim().split(/\n/).filter(function(rect) {
|
||||
var my = rect.match(/y="([0-9\.]+)"/);
|
||||
|
||||
if (!my)
|
||||
return false;
|
||||
var y = +my[1];
|
||||
if (!y)
|
||||
return false;
|
||||
minyOverall = Math.min(minyOverall, y);
|
||||
|
||||
// pluck off everything that will be less than one pixel.
|
||||
var mw = rect.match(/width="([0-9\.]+)"/)
|
||||
if (mw) {
|
||||
var width = +mw[1];
|
||||
if (!(width >= 1))
|
||||
return false;
|
||||
}
|
||||
minyKept = Math.min(minyKept, y);
|
||||
return true;
|
||||
});
|
||||
|
||||
// move everything up to the top of the page.
|
||||
var ydiff = minyKept - minyOverall;
|
||||
rects = rects.map(function(rect) {
|
||||
var my = rect.match(/y="([0-9\.]+)"/);
|
||||
var y = +my[1];
|
||||
var newy = y - ydiff;
|
||||
rect = rect.replace(/y="([0-9\.]+)"/, "y=\"" + newy + "\"");
|
||||
return rect;
|
||||
});
|
||||
|
||||
fs.writeFileSync(outfile, head + "\n" + rects.join("\n") + "\n" + tail);
|
||||
' "$name".raw.svg "$name".svg
|
||||
|
||||
echo ''
|
||||
echo 'done. Results in '"$name"'.svg'
|
||||
@@ -1,43 +0,0 @@
|
||||
#!/bin/bash
|
||||
cd "$(dirname "$(dirname $0)")"
|
||||
|
||||
if type sysctl &>/dev/null; then
|
||||
# darwin and linux
|
||||
sudo sysctl -w net.ipv4.ip_local_port_range="12000 65535"
|
||||
sudo sysctl -w net.inet.ip.portrange.first=12000
|
||||
sudo sysctl -w net.inet.tcp.msl=1000
|
||||
sudo sysctl -w kern.maxfiles=1000000 kern.maxfilesperproc=1000000
|
||||
elif type /usr/sbin/ndd &>/dev/null; then
|
||||
# sunos
|
||||
/usr/sbin/ndd -set /dev/tcp tcp_smallest_anon_port 12000
|
||||
/usr/sbin/ndd -set /dev/tcp tcp_largest_anon_port 65535
|
||||
/usr/sbin/ndd -set /dev/tcp tcp_max_buf 2097152
|
||||
/usr/sbin/ndd -set /dev/tcp tcp_xmit_hiwat 1048576
|
||||
/usr/sbin/ndd -set /dev/tcp tcp_recv_hiwat 1048576
|
||||
fi
|
||||
|
||||
ulimit -n 100000
|
||||
|
||||
k=${KEEPALIVE}
|
||||
if [ "$k" = "no" ]; then
|
||||
k=""
|
||||
else
|
||||
k="-k"
|
||||
fi
|
||||
node=${NODE:-./node}
|
||||
|
||||
$node benchmark/http_simple.js &
|
||||
npid=$!
|
||||
|
||||
sleep 1
|
||||
|
||||
if [ "$k" = "-k" ]; then
|
||||
echo "using keepalive"
|
||||
fi
|
||||
|
||||
for i in a a a a a a a a a a a a a a a a a a a a; do
|
||||
ab $k -t 10 -c 100 http://127.0.0.1:8000/${TYPE:-bytes}/${LENGTH:-1024} \
|
||||
2>&1 | grep Req | egrep -o '[0-9\.]+'
|
||||
done
|
||||
|
||||
kill $npid
|
||||
@@ -1,42 +0,0 @@
|
||||
// When calling .end(buffer) right away, this triggers a "hot path"
|
||||
// optimization in http.js, to avoid an extra write call.
|
||||
//
|
||||
// However, the overhead of copying a large buffer is higher than
|
||||
// the overhead of an extra write() call, so the hot path was not
|
||||
// always as hot as it could be.
|
||||
//
|
||||
// Verify that our assumptions are valid.
|
||||
|
||||
var common = require('../common.js');
|
||||
var PORT = common.PORT;
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
num: [1, 4, 8, 16],
|
||||
size: [1, 64, 256],
|
||||
c: [100]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
http = require('http');
|
||||
var chunk = new Buffer(conf.size);
|
||||
chunk.fill('8');
|
||||
|
||||
var args = ['-d', '10s', '-t', 8, '-c', conf.c];
|
||||
|
||||
var server = http.createServer(function(req, res) {
|
||||
function send(left) {
|
||||
if (left === 0) return res.end();
|
||||
res.write(chunk);
|
||||
setTimeout(function() {
|
||||
send(left - 1);
|
||||
}, 0);
|
||||
}
|
||||
send(conf.num);
|
||||
});
|
||||
|
||||
server.listen(common.PORT, function() {
|
||||
bench.http('/', args, function() {
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
// Measure the time it takes for the HTTP client to send a request body.
|
||||
|
||||
var common = require('../common.js');
|
||||
var http = require('http');
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
dur: [5],
|
||||
type: ['asc', 'utf', 'buf'],
|
||||
bytes: [32, 256, 1024],
|
||||
method: ['write', 'end '] // two spaces added to line up each row
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var dur = +conf.dur;
|
||||
var len = +conf.bytes;
|
||||
|
||||
var encoding;
|
||||
var chunk;
|
||||
switch (conf.type) {
|
||||
case 'buf':
|
||||
chunk = new Buffer(len);
|
||||
chunk.fill('x');
|
||||
break;
|
||||
case 'utf':
|
||||
encoding = 'utf8';
|
||||
chunk = new Array(len / 2 + 1).join('ü');
|
||||
break;
|
||||
case 'asc':
|
||||
chunk = new Array(len + 1).join('a');
|
||||
break;
|
||||
}
|
||||
|
||||
var nreqs = 0;
|
||||
var options = {
|
||||
headers: { 'Connection': 'keep-alive', 'Transfer-Encoding': 'chunked' },
|
||||
agent: new http.Agent({ maxSockets: 1 }),
|
||||
host: '127.0.0.1',
|
||||
port: common.PORT,
|
||||
path: '/',
|
||||
method: 'POST'
|
||||
};
|
||||
|
||||
var server = http.createServer(function(req, res) {
|
||||
res.end();
|
||||
});
|
||||
server.listen(options.port, options.host, function() {
|
||||
setTimeout(done, dur * 1000);
|
||||
bench.start();
|
||||
pummel();
|
||||
});
|
||||
|
||||
function pummel() {
|
||||
var req = http.request(options, function(res) {
|
||||
nreqs++;
|
||||
pummel(); // Line up next request.
|
||||
res.resume();
|
||||
});
|
||||
if (conf.method === 'write') {
|
||||
req.write(chunk, encoding);
|
||||
req.end();
|
||||
} else {
|
||||
req.end(chunk, encoding);
|
||||
}
|
||||
}
|
||||
|
||||
function done() {
|
||||
bench.end(nreqs);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
var PORT = common.PORT;
|
||||
|
||||
var cluster = require('cluster');
|
||||
if (cluster.isMaster) {
|
||||
var bench = common.createBenchmark(main, {
|
||||
// unicode confuses ab on os x.
|
||||
type: ['bytes', 'buffer'],
|
||||
length: [4, 1024, 102400],
|
||||
c: [50, 500]
|
||||
});
|
||||
} else {
|
||||
require('../http_simple.js');
|
||||
}
|
||||
|
||||
function main(conf) {
|
||||
process.env.PORT = PORT;
|
||||
var workers = 0;
|
||||
var w1 = cluster.fork();
|
||||
var w2 = cluster.fork();
|
||||
|
||||
cluster.on('listening', function() {
|
||||
workers++;
|
||||
if (workers < 2)
|
||||
return;
|
||||
|
||||
setTimeout(function() {
|
||||
var path = '/' + conf.type + '/' + conf.length;
|
||||
var args = ['-d', '10s', '-t', 8, '-c', conf.c];
|
||||
|
||||
bench.http(path, args, function() {
|
||||
w1.destroy();
|
||||
w2.destroy();
|
||||
});
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
// When calling .end(buffer) right away, this triggers a "hot path"
|
||||
// optimization in http.js, to avoid an extra write call.
|
||||
//
|
||||
// However, the overhead of copying a large buffer is higher than
|
||||
// the overhead of an extra write() call, so the hot path was not
|
||||
// always as hot as it could be.
|
||||
//
|
||||
// Verify that our assumptions are valid.
|
||||
|
||||
var common = require('../common.js');
|
||||
var PORT = common.PORT;
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
type: ['asc', 'utf', 'buf'],
|
||||
kb: [64, 128, 256, 1024],
|
||||
c: [100],
|
||||
method: ['write', 'end '] // two spaces added to line up each row
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
http = require('http');
|
||||
var chunk;
|
||||
var len = conf.kb * 1024;
|
||||
switch (conf.type) {
|
||||
case 'buf':
|
||||
chunk = new Buffer(len);
|
||||
chunk.fill('x');
|
||||
break;
|
||||
case 'utf':
|
||||
encoding = 'utf8';
|
||||
chunk = new Array(len / 2 + 1).join('ü');
|
||||
break;
|
||||
case 'asc':
|
||||
chunk = new Array(len + 1).join('a');
|
||||
break;
|
||||
}
|
||||
|
||||
function write(res) {
|
||||
res.write(chunk);
|
||||
res.end();
|
||||
}
|
||||
|
||||
function end(res) {
|
||||
res.end(chunk);
|
||||
}
|
||||
|
||||
var method = conf.method === 'write' ? write : end;
|
||||
var args = ['-d', '10s', '-t', 8, '-c', conf.c];
|
||||
|
||||
var server = http.createServer(function(req, res) {
|
||||
method(res);
|
||||
});
|
||||
|
||||
server.listen(common.PORT, function() {
|
||||
bench.http('/', args, function() {
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
var PORT = common.PORT;
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
// unicode confuses ab on os x.
|
||||
type: ['bytes', 'buffer'],
|
||||
length: [4, 1024, 102400],
|
||||
chunks: [0, 1, 4], // chunks=0 means 'no chunked encoding'.
|
||||
c: [50, 500]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
process.env.PORT = PORT;
|
||||
var spawn = require('child_process').spawn;
|
||||
var server = require('../http_simple.js');
|
||||
setTimeout(function() {
|
||||
var path = '/' + conf.type + '/' + conf.length + '/' + conf.chunks;
|
||||
var args = ['-d', '10s', '-t', 8, '-c', conf.c];
|
||||
|
||||
bench.http(path, args, function() {
|
||||
server.close();
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var spawn = require('child_process').spawn;
|
||||
var cluster = require('cluster');
|
||||
var http = require('http');
|
||||
|
||||
var options = {
|
||||
mode: 'master',
|
||||
host: '127.0.0.1',
|
||||
port: 22344,
|
||||
path: '/',
|
||||
servers: 1,
|
||||
clients: 1
|
||||
};
|
||||
|
||||
for (var i = 2; i < process.argv.length; ++i) {
|
||||
var args = process.argv[i].split('=', 2);
|
||||
var key = args[0];
|
||||
var val = args[1];
|
||||
options[key] = val;
|
||||
}
|
||||
|
||||
switch (options.mode) {
|
||||
case 'master': startMaster(); break;
|
||||
case 'server': startServer(); break;
|
||||
case 'client': startClient(); break;
|
||||
default: throw new Error('Bad mode: ' + options.mode);
|
||||
}
|
||||
|
||||
process.title = 'http_bench[' + options.mode + ']';
|
||||
|
||||
// monkey-patch the log functions so they include name + pid
|
||||
console.log = patch(console.log);
|
||||
console.trace = patch(console.trace);
|
||||
console.error = patch(console.error);
|
||||
|
||||
function patch(fun) {
|
||||
var prefix = process.title + '[' + process.pid + '] ';
|
||||
return function() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
args[0] = prefix + args[0];
|
||||
return fun.apply(console, args);
|
||||
};
|
||||
}
|
||||
|
||||
function startMaster() {
|
||||
if (!cluster.isMaster) return startServer();
|
||||
|
||||
for (var i = ~~options.servers; i > 0; --i) cluster.fork();
|
||||
|
||||
for (var i = ~~options.clients; i > 0; --i) {
|
||||
var cp = spawn(process.execPath, [__filename, 'mode=client']);
|
||||
cp.stdout.pipe(process.stdout);
|
||||
cp.stderr.pipe(process.stderr);
|
||||
}
|
||||
}
|
||||
|
||||
function startServer() {
|
||||
http.createServer(onRequest).listen(options.port, options.host);
|
||||
|
||||
var body = Array(1024).join('x');
|
||||
var headers = {'Content-Length': '' + body.length};
|
||||
|
||||
function onRequest(req, res) {
|
||||
req.on('error', onError);
|
||||
res.on('error', onError);
|
||||
res.writeHead(200, headers);
|
||||
res.end(body);
|
||||
}
|
||||
|
||||
function onError(err) {
|
||||
console.error(err.stack);
|
||||
}
|
||||
}
|
||||
|
||||
function startClient() {
|
||||
// send off a bunch of concurrent requests
|
||||
// TODO make configurable
|
||||
sendRequest();
|
||||
sendRequest();
|
||||
|
||||
function sendRequest() {
|
||||
var req = http.request(options, onConnection);
|
||||
req.on('error', onError);
|
||||
req.end();
|
||||
}
|
||||
|
||||
// add a little back-off to prevent EADDRNOTAVAIL errors, it's pretty easy
|
||||
// to exhaust the available port range
|
||||
function relaxedSendRequest() {
|
||||
setTimeout(sendRequest, 1);
|
||||
}
|
||||
|
||||
function onConnection(res) {
|
||||
res.on('error', onError);
|
||||
res.on('data', onData);
|
||||
res.on('end', relaxedSendRequest);
|
||||
}
|
||||
|
||||
function onError(err) {
|
||||
console.error(err.stack);
|
||||
relaxedSendRequest();
|
||||
}
|
||||
|
||||
function onData(data) {
|
||||
// this space intentionally left blank
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
var http = require('http');
|
||||
var port = parseInt(process.env.PORT, 10) || 8000;
|
||||
var defaultLag = parseInt(process.argv[2], 10) || 100;
|
||||
|
||||
http.createServer(function(req, res) {
|
||||
res.writeHead(200, { 'content-type': 'text/plain',
|
||||
'content-length': '2' });
|
||||
|
||||
var lag = parseInt(req.url.split("/").pop(), 10) || defaultLag;
|
||||
setTimeout(function() {
|
||||
res.end('ok');
|
||||
}, lag);
|
||||
}).listen(port, 'localhost');
|
||||
@@ -1,120 +1,80 @@
|
||||
var path = require('path'),
|
||||
exec = require('child_process').exec,
|
||||
http = require('http');
|
||||
path = require("path");
|
||||
Buffer = require("buffer").Buffer;
|
||||
|
||||
var port = parseInt(process.env.PORT || 8000);
|
||||
port = parseInt(process.env.PORT || 8000);
|
||||
|
||||
var fixed = makeString(20 * 1024, 'C'),
|
||||
storedBytes = {},
|
||||
storedBuffer = {},
|
||||
storedUnicode = {};
|
||||
var old = (process.argv[2] == 'old');
|
||||
|
||||
var useDomains = process.env.NODE_USE_DOMAINS;
|
||||
console.log('pid ' + process.pid);
|
||||
|
||||
// set up one global domain.
|
||||
if (useDomains) {
|
||||
var domain = require('domain');
|
||||
var gdom = domain.create();
|
||||
gdom.on('error', function(er) {
|
||||
console.error('Error on global domain', er);
|
||||
throw er;
|
||||
});
|
||||
gdom.enter();
|
||||
http = require(old ? "http_old" : 'http');
|
||||
if (old) console.log('old version');
|
||||
|
||||
fixed = ""
|
||||
for (var i = 0; i < 20*1024; i++) {
|
||||
fixed += "C";
|
||||
}
|
||||
|
||||
var server = module.exports = http.createServer(function (req, res) {
|
||||
if (useDomains) {
|
||||
var dom = domain.create();
|
||||
dom.add(req);
|
||||
dom.add(res);
|
||||
}
|
||||
stored = {};
|
||||
storedBuffer = {};
|
||||
|
||||
var commands = req.url.split('/');
|
||||
http.createServer(function (req, res) {
|
||||
var commands = req.url.split("/");
|
||||
var command = commands[1];
|
||||
var body = '';
|
||||
var body = "";
|
||||
var arg = commands[2];
|
||||
var n_chunks = parseInt(commands[3], 10);
|
||||
var status = 200;
|
||||
|
||||
if (command == 'bytes') {
|
||||
var n = ~~arg;
|
||||
if (command == "bytes") {
|
||||
var n = parseInt(arg, 10)
|
||||
if (n <= 0)
|
||||
throw new Error('bytes called with n <= 0')
|
||||
if (storedBytes[n] === undefined) {
|
||||
storedBytes[n] = makeString(n, 'C');
|
||||
throw "bytes called with n <= 0"
|
||||
if (stored[n] === undefined) {
|
||||
console.log("create stored[n]");
|
||||
stored[n] = "";
|
||||
for (var i = 0; i < n; i++) {
|
||||
stored[n] += "C"
|
||||
}
|
||||
}
|
||||
body = storedBytes[n];
|
||||
body = stored[n];
|
||||
|
||||
} else if (command == 'buffer') {
|
||||
var n = ~~arg;
|
||||
if (n <= 0)
|
||||
throw new Error('buffer called with n <= 0');
|
||||
} else if (command == "buffer") {
|
||||
var n = parseInt(arg, 10)
|
||||
if (n <= 0) throw new Error("bytes called with n <= 0");
|
||||
if (storedBuffer[n] === undefined) {
|
||||
console.log("create storedBuffer[n]");
|
||||
storedBuffer[n] = new Buffer(n);
|
||||
for (var i = 0; i < n; i++) {
|
||||
storedBuffer[n][i] = 'C'.charCodeAt(0);
|
||||
storedBuffer[n][i] = "C".charCodeAt(0);
|
||||
}
|
||||
}
|
||||
body = storedBuffer[n];
|
||||
|
||||
} else if (command == 'unicode') {
|
||||
var n = ~~arg;
|
||||
if (n <= 0)
|
||||
throw new Error('unicode called with n <= 0');
|
||||
if (storedUnicode[n] === undefined) {
|
||||
storedUnicode[n] = makeString(n, '\u263A');
|
||||
}
|
||||
body = storedUnicode[n];
|
||||
|
||||
} else if (command == 'quit') {
|
||||
} else if (command == "quit") {
|
||||
res.connection.server.close();
|
||||
body = 'quitting';
|
||||
body = "quitting";
|
||||
|
||||
} else if (command == 'fixed') {
|
||||
} else if (command == "fixed") {
|
||||
body = fixed;
|
||||
|
||||
} else if (command == 'echo') {
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain',
|
||||
'Transfer-Encoding': 'chunked' });
|
||||
req.pipe(res);
|
||||
return;
|
||||
|
||||
} else {
|
||||
status = 404;
|
||||
body = 'not found\n';
|
||||
body = "not found\n";
|
||||
}
|
||||
|
||||
// example: http://localhost:port/bytes/512/4
|
||||
// sends a 512 byte body in 4 chunks of 128 bytes
|
||||
if (n_chunks > 0) {
|
||||
res.writeHead(status, { 'Content-Type': 'text/plain',
|
||||
'Transfer-Encoding': 'chunked' });
|
||||
// send body in chunks
|
||||
var len = body.length;
|
||||
var step = Math.floor(len / n_chunks) || 1;
|
||||
var content_length = body.length.toString();
|
||||
|
||||
for (var i = 0, n = (n_chunks - 1); i < n; ++i) {
|
||||
res.write(body.slice(i * step, i * step + step));
|
||||
}
|
||||
res.end(body.slice((n_chunks - 1) * step));
|
||||
res.writeHead( status
|
||||
, { "Content-Type": "text/plain"
|
||||
, "Content-Length": content_length
|
||||
}
|
||||
);
|
||||
if (old) {
|
||||
res.write(body, 'ascii');
|
||||
res.close();
|
||||
} else {
|
||||
var content_length = body.length.toString();
|
||||
|
||||
res.writeHead(status, { 'Content-Type': 'text/plain',
|
||||
'Content-Length': content_length });
|
||||
res.end(body);
|
||||
res.end(body, 'ascii');
|
||||
}
|
||||
});
|
||||
}).listen(port);
|
||||
|
||||
function makeString(size, c) {
|
||||
var s = '';
|
||||
while (s.length < size) {
|
||||
s += c;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
server.listen(port, function () {
|
||||
if (module === require.main)
|
||||
console.error('Listening at http://127.0.0.1:'+port+'/');
|
||||
});
|
||||
console.log('Listening at http://127.0.0.1:'+port+'/');
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
//
|
||||
// Usage:
|
||||
// node benchmark/http_simple_auto.js <args> <target>
|
||||
//
|
||||
// Where:
|
||||
// <args> Arguments to pass to `ab`.
|
||||
// <target> Target to benchmark, e.g. `bytes/1024` or `buffer/8192`.
|
||||
//
|
||||
|
||||
var path = require("path");
|
||||
var http = require("http");
|
||||
var spawn = require("child_process").spawn;
|
||||
|
||||
var port = parseInt(process.env.PORT || 8000);
|
||||
|
||||
var fixed = ""
|
||||
for (var i = 0; i < 20*1024; i++) {
|
||||
fixed += "C";
|
||||
}
|
||||
|
||||
var stored = {};
|
||||
var storedBuffer = {};
|
||||
|
||||
var server = http.createServer(function (req, res) {
|
||||
var commands = req.url.split("/");
|
||||
var command = commands[1];
|
||||
var body = "";
|
||||
var arg = commands[2];
|
||||
var n_chunks = parseInt(commands[3], 10);
|
||||
var status = 200;
|
||||
|
||||
if (command == "bytes") {
|
||||
var n = parseInt(arg, 10)
|
||||
if (n <= 0)
|
||||
throw "bytes called with n <= 0"
|
||||
if (stored[n] === undefined) {
|
||||
stored[n] = "";
|
||||
for (var i = 0; i < n; i++) {
|
||||
stored[n] += "C"
|
||||
}
|
||||
}
|
||||
body = stored[n];
|
||||
|
||||
} else if (command == "buffer") {
|
||||
var n = parseInt(arg, 10)
|
||||
if (n <= 0) throw new Error("bytes called with n <= 0");
|
||||
if (storedBuffer[n] === undefined) {
|
||||
storedBuffer[n] = new Buffer(n);
|
||||
for (var i = 0; i < n; i++) {
|
||||
storedBuffer[n][i] = "C".charCodeAt(0);
|
||||
}
|
||||
}
|
||||
body = storedBuffer[n];
|
||||
|
||||
} else if (command == "quit") {
|
||||
res.connection.server.close();
|
||||
body = "quitting";
|
||||
|
||||
} else if (command == "fixed") {
|
||||
body = fixed;
|
||||
|
||||
} else if (command == "echo") {
|
||||
res.writeHead(200, { "Content-Type": "text/plain",
|
||||
"Transfer-Encoding": "chunked" });
|
||||
req.pipe(res);
|
||||
return;
|
||||
|
||||
} else {
|
||||
status = 404;
|
||||
body = "not found\n";
|
||||
}
|
||||
|
||||
// example: http://localhost:port/bytes/512/4
|
||||
// sends a 512 byte body in 4 chunks of 128 bytes
|
||||
if (n_chunks > 0) {
|
||||
res.writeHead(status, { "Content-Type": "text/plain",
|
||||
"Transfer-Encoding": "chunked" });
|
||||
// send body in chunks
|
||||
var len = body.length;
|
||||
var step = Math.floor(len / n_chunks) || 1;
|
||||
|
||||
for (var i = 0, n = (n_chunks - 1); i < n; ++i) {
|
||||
res.write(body.slice(i * step, i * step + step));
|
||||
}
|
||||
res.end(body.slice((n_chunks - 1) * step));
|
||||
} else {
|
||||
var content_length = body.length.toString();
|
||||
|
||||
res.writeHead(status, { "Content-Type": "text/plain",
|
||||
"Content-Length": content_length });
|
||||
res.end(body);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
server.listen(port, function () {
|
||||
var url = 'http://127.0.0.1:' + port + '/';
|
||||
|
||||
var n = process.argv.length - 1;
|
||||
process.argv[n] = url + process.argv[n];
|
||||
|
||||
var cp = spawn('ab', process.argv.slice(2));
|
||||
cp.stdout.pipe(process.stdout);
|
||||
cp.stderr.pipe(process.stderr);
|
||||
cp.on('exit', function() {
|
||||
server.close();
|
||||
process.nextTick(dump_mm_stats);
|
||||
});
|
||||
});
|
||||
|
||||
function dump_mm_stats() {
|
||||
if (typeof gc != 'function') return;
|
||||
|
||||
var before = process.memoryUsage();
|
||||
for (var i = 0; i < 10; ++i) gc();
|
||||
var after = process.memoryUsage();
|
||||
setTimeout(print_stats, 250); // give GC time to settle
|
||||
|
||||
function print_stats() {
|
||||
console.log('\nBEFORE / AFTER GC');
|
||||
['rss', 'heapTotal', 'heapUsed'].forEach(function(key) {
|
||||
var a = before[key] / (1024 * 1024);
|
||||
var b = after[key] / (1024 * 1024);
|
||||
console.log('%sM / %sM %s', a.toFixed(2), b.toFixed(2), key);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
SERVER=127.0.0.1
|
||||
PORT=${PORT:=8000}
|
||||
|
||||
# You may want to configure your TCP settings to make many ports available
|
||||
# to node and ab. On macintosh use:
|
||||
# sudo sysctl -w net.inet.ip.portrange.first=32768
|
||||
# sudo sysctl -w net.inet.tcp.msl=1000
|
||||
|
||||
if [ ! -d benchmark/ ]; then
|
||||
echo "Run this script from the node root directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $SERVER == "127.0.0.1" ]; then
|
||||
./node benchmark/http_simple.js &
|
||||
node_pid=$!
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
date=`date "+%Y%m%d%H%M%S"`
|
||||
|
||||
ab_hello_world() {
|
||||
local type="$1"
|
||||
local ressize="$2"
|
||||
if [ $type == "string" ]; then
|
||||
local uri="bytes/$ressize"
|
||||
else
|
||||
local uri="buffer/$ressize"
|
||||
fi
|
||||
|
||||
|
||||
name="ab-hello-world-$type-$ressize"
|
||||
|
||||
dir=".benchmark_reports/$name/$rev/"
|
||||
if [ ! -d $dir ]; then
|
||||
mkdir -p $dir
|
||||
fi
|
||||
|
||||
summary_fn="$dir/$date.summary"
|
||||
data_fn="$dir/$date.data"
|
||||
|
||||
echo "Bench $name starts in 3 seconds..."
|
||||
# let shit calm down
|
||||
sleep 3
|
||||
|
||||
# hammer that as hard as it can for 10 seconds.
|
||||
ab -g $data_fn -c 100 -t 10 http://$SERVER:$PORT/$uri > $summary_fn
|
||||
|
||||
# add our data about the server
|
||||
echo >> $summary_fn
|
||||
echo >> $summary_fn
|
||||
echo "webserver-rev: $rev" >> $summary_fn
|
||||
echo "webserver-uname: $uname" >> $summary_fn
|
||||
|
||||
grep Req $summary_fn
|
||||
|
||||
echo "Summary: $summary_fn"
|
||||
echo
|
||||
}
|
||||
|
||||
# 1k
|
||||
ab_hello_world 'string' '1024'
|
||||
ab_hello_world 'buffer' '1024'
|
||||
|
||||
# 100k
|
||||
ab_hello_world 'string' '102400'
|
||||
ab_hello_world 'buffer' '102400'
|
||||
|
||||
|
||||
if [ ! -z $node_pid ]; then
|
||||
kill -9 $node_pid
|
||||
fi
|
||||
@@ -1,9 +0,0 @@
|
||||
var cluster = require('cluster');
|
||||
var os = require('os');
|
||||
|
||||
if (cluster.isMaster) {
|
||||
console.log('master running on pid %d', process.pid);
|
||||
for (var i = 0, n = os.cpus().length; i < n; ++i) cluster.fork();
|
||||
} else {
|
||||
require(__dirname + '/http_simple.js');
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
net = require('net');
|
||||
|
||||
var errors = 0, connections = 0;
|
||||
|
||||
var lastClose = 0;
|
||||
|
||||
function connect () {
|
||||
process.nextTick(function () {
|
||||
var s = net.Stream();
|
||||
var gotConnected = false;
|
||||
s.connect(9000);
|
||||
|
||||
s.on('connect', function () {
|
||||
gotConnected = true;
|
||||
connections++;
|
||||
connect();
|
||||
});
|
||||
|
||||
s.on('close', function () {
|
||||
if (gotConnected) connections--;
|
||||
lastClose = new Date();
|
||||
});
|
||||
|
||||
s.on('error', function () {
|
||||
errors++;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
connect();
|
||||
|
||||
|
||||
var oldConnections, oldErrors;
|
||||
|
||||
// Try to start new connections every so often
|
||||
setInterval(connect, 5000);
|
||||
|
||||
setInterval(function () {
|
||||
if (oldConnections != connections) {
|
||||
oldConnections = connections;
|
||||
console.log("CLIENT %d connections: %d", process.pid, connections);
|
||||
}
|
||||
|
||||
if (oldErrors != errors) {
|
||||
oldErrors = errors;
|
||||
console.log("CLIENT %d errors: %d", process.pid, errors);
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
net = require('net');
|
||||
connections = 0;
|
||||
|
||||
var errors = 0;
|
||||
|
||||
server = net.Server(function (socket) {
|
||||
|
||||
socket.on('error', function () {
|
||||
errors++;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//server.maxConnections = 128;
|
||||
|
||||
server.listen(9000);
|
||||
|
||||
var oldConnections, oldErrors;
|
||||
|
||||
setInterval(function () {
|
||||
if (oldConnections != server.connections) {
|
||||
oldConnections = server.connections;
|
||||
console.log("SERVER %d connections: %d", process.pid, server.connections);
|
||||
}
|
||||
|
||||
if (oldErrors != errors) {
|
||||
oldErrors = errors;
|
||||
console.log("SERVER %d errors: %d", process.pid, errors);
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
@@ -2,89 +2,78 @@
|
||||
* gcc -o iotest io.c
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static int c = 0;
|
||||
static int tsize = 1000 * 1048576;
|
||||
static const char* path = "/tmp/wt.dat";
|
||||
static char buf[65536];
|
||||
int tsize = 1000 * 1048576;
|
||||
const char *path = "/tmp/wt.dat";
|
||||
|
||||
static uint64_t now(void) {
|
||||
struct timeval tv;
|
||||
int c = 0;
|
||||
|
||||
if (gettimeofday(&tv, NULL))
|
||||
abort();
|
||||
|
||||
return tv.tv_sec * 1000000ULL + tv.tv_usec;
|
||||
char* bufit(size_t l)
|
||||
{
|
||||
char *p = malloc(l);
|
||||
memset(p, '!', l);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void writetest(int size, size_t bsize)
|
||||
void writetest(int size, size_t bsize)
|
||||
{
|
||||
int i;
|
||||
uint64_t start, end;
|
||||
char *buf = bufit(bsize);
|
||||
struct timeval start, end;
|
||||
double elapsed;
|
||||
double mbps;
|
||||
|
||||
assert(bsize <= sizeof buf);
|
||||
|
||||
int fd = open(path, O_CREAT|O_WRONLY, 0644);
|
||||
if (fd < 0) {
|
||||
perror("open failed");
|
||||
exit(254);
|
||||
}
|
||||
|
||||
start = now();
|
||||
|
||||
assert(0 == gettimeofday(&start, NULL));
|
||||
for (i = 0; i < size; i += bsize) {
|
||||
int rv = write(fd, buf, bsize);
|
||||
if (c++ % 2000 == 0) fprintf(stderr, ".");
|
||||
if (rv < 0) {
|
||||
perror("write failed");
|
||||
exit(254);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NSYNC
|
||||
# ifdef __linux__
|
||||
#ifdef __linux__
|
||||
fdatasync(fd);
|
||||
# else
|
||||
#else
|
||||
fsync(fd);
|
||||
# endif
|
||||
#endif /* SYNC */
|
||||
|
||||
#endif
|
||||
close(fd);
|
||||
|
||||
end = now();
|
||||
elapsed = (end - start) / 1e6;
|
||||
assert(0 == gettimeofday(&end, NULL));
|
||||
elapsed = (end.tv_sec - start.tv_sec) + ((double)(end.tv_usec - start.tv_usec))/100000.;
|
||||
mbps = ((tsize/elapsed)) / 1048576;
|
||||
fprintf(stderr, "\nWrote %d bytes in %03fs using %ld byte buffers: %03fmB/s\n", size, elapsed, bsize, mbps);
|
||||
|
||||
fprintf(stderr, "Wrote %d bytes in %03fs using %ld byte buffers: %03f\n", size, elapsed, bsize, mbps);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void readtest(int size, size_t bsize)
|
||||
{
|
||||
int i;
|
||||
uint64_t start, end;
|
||||
char *buf = bufit(bsize);
|
||||
struct timeval start, end;
|
||||
double elapsed;
|
||||
double mbps;
|
||||
|
||||
assert(bsize <= sizeof buf);
|
||||
|
||||
int fd = open(path, O_RDONLY, 0644);
|
||||
if (fd < 0) {
|
||||
perror("open failed");
|
||||
exit(254);
|
||||
}
|
||||
|
||||
start = now();
|
||||
|
||||
assert(0 == gettimeofday(&start, NULL));
|
||||
for (i = 0; i < size; i += bsize) {
|
||||
int rv = read(fd, buf, bsize);
|
||||
if (rv < 0) {
|
||||
@@ -93,25 +82,23 @@ void readtest(int size, size_t bsize)
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
|
||||
end = now();
|
||||
elapsed = (end - start) / 1e6;
|
||||
assert(0 == gettimeofday(&end, NULL));
|
||||
elapsed = (end.tv_sec - start.tv_sec) + ((double)(end.tv_usec - start.tv_usec))/100000.;
|
||||
mbps = ((tsize/elapsed)) / 1048576;
|
||||
|
||||
fprintf(stderr, "Read %d bytes in %03fs using %ld byte buffers: %03fmB/s\n", size, elapsed, bsize, mbps);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
unlink(path);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
int bsizes[] = {1024, 4096, 8192, 16384, 32768, 65536, 0};
|
||||
|
||||
if (argc > 1) path = argv[1];
|
||||
|
||||
for (i = 0; bsizes[i] != 0; i++) {
|
||||
writetest(tsize, bsizes[i]);
|
||||
}
|
||||
|
||||
109
benchmark/io.js
Normal file
109
benchmark/io.js
Normal file
@@ -0,0 +1,109 @@
|
||||
var fs = require('fs');
|
||||
var sys = require('sys');
|
||||
var Buffer = require('buffer').Buffer;
|
||||
|
||||
var path = "/tmp/wt.dat";
|
||||
var tsize = 1000 * 1048576;
|
||||
var bsizes = [1024, 4096, 8192, 16384, 32768, 65536];
|
||||
|
||||
function bufit(size) {
|
||||
var buf = new Buffer(size);
|
||||
for (var i = 0; i <buf.length ; i += 1) {
|
||||
buf[i] = 33;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
function once(emitter, name, cb) {
|
||||
function incb() {
|
||||
cb.apply(undefined, arguments);
|
||||
emitter.removeListener(name, incb);
|
||||
}
|
||||
emitter.addListener(name, incb);
|
||||
}
|
||||
|
||||
c = 0
|
||||
|
||||
function writetest(size, bsize) {
|
||||
var s = fs.createWriteStream(path, {'flags': 'w', 'mode': 0644});
|
||||
var remaining = size;
|
||||
var buf = bufit(bsize);
|
||||
|
||||
function dowrite() {
|
||||
var rv = s.write(buf);
|
||||
remaining -= buf.length;
|
||||
if (remaining > 0) {
|
||||
//if (remaining % 90000 == 0) console.error("remaining: %d", remaining);
|
||||
//process.nextTick(dowrite);
|
||||
} else {
|
||||
s.emit('done')
|
||||
s.end();
|
||||
}
|
||||
}
|
||||
|
||||
s.on('drain', function () {
|
||||
dowrite();
|
||||
if (c++ % 2000 == 0) sys.print(".");
|
||||
});
|
||||
|
||||
dowrite();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
function readtest(size, bsize) {
|
||||
var s = fs.createReadStream(path, {'flags': 'r', 'encoding': 'binary', 'mode': 0644, 'bufferSize': bsize});
|
||||
s.addListener("data", function (chunk) {
|
||||
// got a chunk...
|
||||
|
||||
});
|
||||
return s;
|
||||
}
|
||||
|
||||
function wt(tsize, bsize, done) {
|
||||
var start = Date.now();
|
||||
s = writetest(tsize, bsizes[0]);
|
||||
s.addListener('close', function() {
|
||||
var end = Date.now();
|
||||
var diff = end - start;
|
||||
console.log('Wrote '+ tsize +' bytes in '+ diff/1000 +'s using '+ bsize +' byte buffers: '+ ((tsize/(diff/1000)) / 1048576) +' mB/s');
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
function rt(tsize, bsize, done) {
|
||||
var start = Date.now();
|
||||
s = readtest(tsize, bsizes[0]);
|
||||
s.addListener('close', function() {
|
||||
var end = Date.now();
|
||||
var diff = end - start;
|
||||
console.log('Read '+ tsize +' bytes in '+ diff/1000 +'s using '+ bsize +' byte buffers: '+ ((tsize/(diff/1000)) / 1048576) +' mB/s');
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
var bs= 0;
|
||||
|
||||
function nextwt() {
|
||||
if (bsizes.length <= bs) {
|
||||
bs = 0;
|
||||
nextrt();
|
||||
return;
|
||||
}
|
||||
wt(tsize, bsizes[bs], nextwt);
|
||||
bs += 1;
|
||||
}
|
||||
|
||||
function nextrt() {
|
||||
if (bsizes.length <= bs) {
|
||||
fs.unlink(path, function (err) {
|
||||
if (err) throw err;
|
||||
console.log('All done!');
|
||||
});
|
||||
return;
|
||||
}
|
||||
rt(tsize, bsizes[bs], nextrt);
|
||||
bs += 1;
|
||||
}
|
||||
|
||||
nextwt();
|
||||
@@ -1,28 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
len: [64, 256, 1024, 4096, 32768],
|
||||
dur: [5]
|
||||
});
|
||||
|
||||
var spawn = require('child_process').spawn;
|
||||
function main(conf) {
|
||||
bench.start();
|
||||
|
||||
var dur = +conf.dur;
|
||||
var len = +conf.len;
|
||||
|
||||
var msg = '"' + Array(len).join('.') + '"';
|
||||
var options = { 'stdio': ['ignore', 'ipc', 'ignore'] };
|
||||
var child = spawn('yes', [msg], options);
|
||||
|
||||
var bytes = 0;
|
||||
child.on('message', function(msg) {
|
||||
bytes += msg.length;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
child.kill();
|
||||
var gbits = (bytes * 8) / (1024 * 1024 * 1024);
|
||||
bench.end(gbits);
|
||||
}, dur * 1000);
|
||||
}
|
||||
1
benchmark/misc/function_call/.gitignore
vendored
1
benchmark/misc/function_call/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
build/
|
||||
@@ -1,2 +0,0 @@
|
||||
binding:
|
||||
node-gyp rebuild --nodedir=../../..
|
||||
@@ -1,17 +0,0 @@
|
||||
#include <v8.h>
|
||||
#include <node.h>
|
||||
|
||||
using namespace v8;
|
||||
|
||||
static int c = 0;
|
||||
|
||||
void Hello(const FunctionCallbackInfo<Value>& args) {
|
||||
args.GetReturnValue().Set(c++);
|
||||
}
|
||||
|
||||
extern "C" void init (Handle<Object> target) {
|
||||
HandleScope scope(Isolate::GetCurrent());
|
||||
NODE_SET_METHOD(target, "hello", Hello);
|
||||
}
|
||||
|
||||
NODE_MODULE(binding, init);
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'binding',
|
||||
'sources': [ 'binding.cc' ]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
// show the difference between calling a short js function
|
||||
// relative to a comparable C++ function.
|
||||
// Reports millions of calls per second.
|
||||
// Note that JS speed goes up, while cxx speed stays about the same.
|
||||
|
||||
var assert = require('assert');
|
||||
var common = require('../../common.js');
|
||||
|
||||
// this fails when we try to open with a different version of node,
|
||||
// which is quite common for benchmarks. so in that case, just
|
||||
// abort quietly.
|
||||
|
||||
try {
|
||||
var binding = require('./build/Release/binding');
|
||||
} catch (er) {
|
||||
console.error('misc/function_call.js Binding failed to load');
|
||||
process.exit(0);
|
||||
}
|
||||
var cxx = binding.hello;
|
||||
|
||||
var c = 0;
|
||||
function js() {
|
||||
return c++;
|
||||
}
|
||||
|
||||
assert(js() === cxx());
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
type: ['js', 'cxx'],
|
||||
millions: [1,10,50]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var n = +conf.millions * 1e6;
|
||||
|
||||
var fn = conf.type === 'cxx' ? cxx : js;
|
||||
bench.start();
|
||||
for (var i = 0; i < n; i++) {
|
||||
fn();
|
||||
}
|
||||
bench.end(+conf.millions);
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var common = require('../common.js');
|
||||
var packageJson = '{"main": "index.js"}';
|
||||
|
||||
var tmpDirectory = path.join(__dirname, '..', 'tmp');
|
||||
var benchmarkDirectory = path.join(tmpDirectory, 'nodejs-benchmark-module');
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
thousands: [50]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
rmrf(tmpDirectory);
|
||||
try { fs.mkdirSync(tmpDirectory); } catch (e) {}
|
||||
try { fs.mkdirSync(benchmarkDirectory); } catch (e) {}
|
||||
|
||||
var n = +conf.thousands * 1e3;
|
||||
for (var i = 0; i <= n; i++) {
|
||||
fs.mkdirSync(benchmarkDirectory + i);
|
||||
fs.writeFileSync(benchmarkDirectory + i + '/package.json', '{"main": "index.js"}');
|
||||
fs.writeFileSync(benchmarkDirectory + i + '/index.js', 'module.exports = "";');
|
||||
}
|
||||
|
||||
measure(n);
|
||||
}
|
||||
|
||||
function measure(n) {
|
||||
bench.start();
|
||||
for (var i = 0; i <= n; i++) {
|
||||
require(benchmarkDirectory + i);
|
||||
}
|
||||
bench.end(n / 1e3);
|
||||
}
|
||||
|
||||
function rmrf(location) {
|
||||
if (fs.existsSync(location)) {
|
||||
var things = fs.readdirSync(location);
|
||||
things.forEach(function(thing) {
|
||||
var cur = path.join(location, thing),
|
||||
isDirectory = fs.statSync(cur).isDirectory();
|
||||
if (isDirectory) {
|
||||
rmrf(cur);
|
||||
return;
|
||||
}
|
||||
fs.unlinkSync(cur);
|
||||
});
|
||||
fs.rmdirSync(location);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
millions: [2]
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var N = +conf.millions * 1e6;
|
||||
var n = 0;
|
||||
|
||||
function cb() {
|
||||
n++;
|
||||
if (n === N)
|
||||
bench.end(n / 1e6);
|
||||
}
|
||||
|
||||
bench.start();
|
||||
for (var i = 0; i < N; i++) {
|
||||
process.nextTick(cb);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
millions: [2]
|
||||
});
|
||||
|
||||
process.maxTickDepth = Infinity;
|
||||
|
||||
function main(conf) {
|
||||
var n = +conf.millions * 1e6;
|
||||
|
||||
bench.start();
|
||||
process.nextTick(onNextTick);
|
||||
function onNextTick() {
|
||||
if (--n)
|
||||
process.nextTick(onNextTick);
|
||||
else
|
||||
bench.end(+conf.millions);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
thousands: [1]
|
||||
});
|
||||
|
||||
var spawn = require('child_process').spawn;
|
||||
function main(conf) {
|
||||
var len = +conf.thousands * 1000;
|
||||
|
||||
bench.start();
|
||||
go(len, len);
|
||||
}
|
||||
|
||||
function go(n, left) {
|
||||
if (--left === 0)
|
||||
return bench.end(n);
|
||||
|
||||
var child = spawn('echo', ['hello']);
|
||||
child.on('exit', function(code) {
|
||||
if (code)
|
||||
process.exit(code);
|
||||
else
|
||||
go(n, left);
|
||||
});
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
var spawn = require('child_process').spawn;
|
||||
var path = require('path');
|
||||
var emptyJsFile = path.resolve(__dirname, '../../test/fixtures/semicolon.js');
|
||||
var starts = 100;
|
||||
var i = 0;
|
||||
var start;
|
||||
|
||||
var bench = common.createBenchmark(startNode, {
|
||||
dur: [1]
|
||||
});
|
||||
|
||||
function startNode(conf) {
|
||||
var dur = +conf.dur;
|
||||
var go = true;
|
||||
var starts = 0;
|
||||
var open = 0;
|
||||
|
||||
setTimeout(function() {
|
||||
go = false;
|
||||
}, dur * 1000);
|
||||
|
||||
bench.start();
|
||||
start();
|
||||
|
||||
function start() {
|
||||
var node = spawn(process.execPath || process.argv[0], [emptyJsFile]);
|
||||
node.on('exit', function(exitCode) {
|
||||
if (exitCode !== 0) {
|
||||
throw new Error('Error during node startup');
|
||||
}
|
||||
starts++;
|
||||
|
||||
if (go)
|
||||
start();
|
||||
else
|
||||
bench.end(starts);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
millions: [100]
|
||||
})
|
||||
|
||||
function main(conf) {
|
||||
var n = +conf.millions * 1e6;
|
||||
bench.start();
|
||||
var s;
|
||||
for (var i = 0; i < n; i++) {
|
||||
s = '01234567890';
|
||||
s[1] = "a";
|
||||
}
|
||||
bench.end(n / 1e6);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
thousands: [500],
|
||||
type: ['depth', 'breadth']
|
||||
});
|
||||
|
||||
function main(conf) {
|
||||
var n = +conf.thousands * 1e3;
|
||||
if (conf.type === 'breadth')
|
||||
breadth(n);
|
||||
else
|
||||
depth(n);
|
||||
}
|
||||
|
||||
function depth(N) {
|
||||
var n = 0;
|
||||
bench.start();
|
||||
setTimeout(cb);
|
||||
function cb() {
|
||||
n++;
|
||||
if (n === N)
|
||||
bench.end(N / 1e3);
|
||||
else
|
||||
setTimeout(cb);
|
||||
}
|
||||
}
|
||||
|
||||
function breadth(N) {
|
||||
var n = 0;
|
||||
bench.start();
|
||||
function cb() {
|
||||
n++;
|
||||
if (n === N)
|
||||
bench.end(N / 1e3);
|
||||
}
|
||||
for (var i = 0; i < N; i++) {
|
||||
setTimeout(cb);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
var url = require('url')
|
||||
var n = 25 * 100;
|
||||
|
||||
var urls = [
|
||||
'http://nodejs.org/docs/latest/api/url.html#url_url_format_urlobj',
|
||||
'http://blog.nodejs.org/',
|
||||
'https://encrypted.google.com/search?q=url&q=site:npmjs.org&hl=en',
|
||||
'javascript:alert("node is awesome");',
|
||||
'some.ran/dom/url.thing?oh=yes#whoo'
|
||||
];
|
||||
|
||||
var paths = [
|
||||
'../foo/bar?baz=boom',
|
||||
'foo/bar',
|
||||
'http://nodejs.org',
|
||||
'./foo/bar?baz'
|
||||
];
|
||||
|
||||
benchmark('parse()', url.parse);
|
||||
benchmark('format()', url.format);
|
||||
paths.forEach(function(p) {
|
||||
benchmark('resolve("' + p + '")', function(u) {
|
||||
url.resolve(u, p)
|
||||
});
|
||||
});
|
||||
|
||||
function benchmark(name, fun) {
|
||||
var timestamp = process.hrtime();
|
||||
for (var i = 0; i < n; ++i) {
|
||||
for (var j = 0, k = urls.length; j < k; ++j) fun(urls[j]);
|
||||
}
|
||||
timestamp = process.hrtime(timestamp);
|
||||
|
||||
var seconds = timestamp[0];
|
||||
var nanos = timestamp[1];
|
||||
var time = seconds + nanos / 1e9;
|
||||
var rate = n / time;
|
||||
|
||||
console.log('misc/url.js %s: %s', name, rate.toPrecision(5));
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// compare with "google-chrome deps/v8/benchmarks/run.html"
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var vm = require('vm');
|
||||
|
||||
var dir = path.join(__dirname, '..', '..', 'deps', 'v8', 'benchmarks');
|
||||
|
||||
global.print = function(s) {
|
||||
if (s === '----') return;
|
||||
console.log('misc/v8_bench.js %s', s);
|
||||
};
|
||||
|
||||
global.load = function (x) {
|
||||
var source = fs.readFileSync(path.join(dir, x), 'utf8');
|
||||
vm.runInThisContext(source, x);
|
||||
}
|
||||
|
||||
load('run.js');
|
||||
@@ -1,61 +0,0 @@
|
||||
// test UDP send/recv throughput
|
||||
|
||||
var common = require('../common.js');
|
||||
var PORT = common.PORT;
|
||||
|
||||
// `num` is the number of send requests to queue up each time.
|
||||
// Keep it reasonably high (>10) otherwise you're benchmarking the speed of
|
||||
// event loop cycles more than anything else.
|
||||
var bench = common.createBenchmark(main, {
|
||||
len: [1, 64, 256, 1024],
|
||||
num: [100],
|
||||
type: ['send', 'recv'],
|
||||
dur: [5]
|
||||
});
|
||||
|
||||
var dur;
|
||||
var len;
|
||||
var num;
|
||||
var type;
|
||||
var chunk;
|
||||
var encoding;
|
||||
|
||||
function main(conf) {
|
||||
dur = +conf.dur;
|
||||
len = +conf.len;
|
||||
num = +conf.num;
|
||||
type = conf.type;
|
||||
chunk = new Buffer(len);
|
||||
server();
|
||||
}
|
||||
|
||||
var dgram = require('dgram');
|
||||
|
||||
function server() {
|
||||
var sent = 0;
|
||||
var received = 0;
|
||||
var socket = dgram.createSocket('udp4');
|
||||
|
||||
function onsend() {
|
||||
if (sent++ % num == 0)
|
||||
for (var i = 0; i < num; i++)
|
||||
socket.send(chunk, 0, chunk.length, PORT, '127.0.0.1', onsend);
|
||||
}
|
||||
|
||||
socket.on('listening', function() {
|
||||
bench.start();
|
||||
onsend();
|
||||
|
||||
setTimeout(function() {
|
||||
var bytes = (type === 'send' ? sent : received) * chunk.length;
|
||||
var gbits = (bytes * 8) / (1024 * 1024 * 1024);
|
||||
bench.end(gbits);
|
||||
}, dur * 1000);
|
||||
});
|
||||
|
||||
socket.on('message', function(buf, rinfo) {
|
||||
received++;
|
||||
});
|
||||
|
||||
socket.bind(PORT);
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
// test the speed of .pipe() with sockets
|
||||
|
||||
var common = require('../common.js');
|
||||
var PORT = common.PORT;
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
len: [102400, 1024 * 1024 * 16],
|
||||
type: ['utf', 'asc', 'buf'],
|
||||
dur: [5],
|
||||
});
|
||||
|
||||
var dur;
|
||||
var len;
|
||||
var type;
|
||||
var chunk;
|
||||
var encoding;
|
||||
|
||||
function main(conf) {
|
||||
dur = +conf.dur;
|
||||
len = +conf.len;
|
||||
type = conf.type;
|
||||
|
||||
switch (type) {
|
||||
case 'buf':
|
||||
chunk = new Buffer(len);
|
||||
chunk.fill('x');
|
||||
break;
|
||||
case 'utf':
|
||||
encoding = 'utf8';
|
||||
chunk = new Array(len / 2 + 1).join('ü');
|
||||
break;
|
||||
case 'asc':
|
||||
encoding = 'ascii';
|
||||
chunk = new Array(len + 1).join('x');
|
||||
break;
|
||||
default:
|
||||
throw new Error('invalid type: ' + type);
|
||||
break;
|
||||
}
|
||||
|
||||
server();
|
||||
}
|
||||
|
||||
var net = require('net');
|
||||
|
||||
function Writer() {
|
||||
this.received = 0;
|
||||
this.writable = true;
|
||||
}
|
||||
|
||||
Writer.prototype.write = function(chunk, encoding, cb) {
|
||||
this.received += chunk.length;
|
||||
|
||||
if (typeof encoding === 'function')
|
||||
encoding();
|
||||
else if (typeof cb === 'function')
|
||||
cb();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// doesn't matter, never emits anything.
|
||||
Writer.prototype.on = function() {};
|
||||
Writer.prototype.once = function() {};
|
||||
Writer.prototype.emit = function() {};
|
||||
|
||||
|
||||
function Reader() {
|
||||
this.flow = this.flow.bind(this);
|
||||
this.readable = true;
|
||||
}
|
||||
|
||||
Reader.prototype.pipe = function(dest) {
|
||||
this.dest = dest;
|
||||
this.flow();
|
||||
return dest;
|
||||
};
|
||||
|
||||
Reader.prototype.flow = function() {
|
||||
var dest = this.dest;
|
||||
var res = dest.write(chunk, encoding);
|
||||
if (!res)
|
||||
dest.once('drain', this.flow);
|
||||
else
|
||||
process.nextTick(this.flow);
|
||||
};
|
||||
|
||||
|
||||
function server() {
|
||||
var reader = new Reader();
|
||||
var writer = new Writer();
|
||||
|
||||
// the actual benchmark.
|
||||
var server = net.createServer(function(socket) {
|
||||
socket.pipe(writer);
|
||||
});
|
||||
|
||||
server.listen(PORT, function() {
|
||||
var socket = net.connect(PORT);
|
||||
socket.on('connect', function() {
|
||||
bench.start();
|
||||
|
||||
reader.pipe(socket);
|
||||
|
||||
setTimeout(function() {
|
||||
var bytes = writer.received;
|
||||
var gbits = (bytes * 8) / (1024 * 1024 * 1024);
|
||||
bench.end(gbits);
|
||||
}, dur * 1000);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
// test the speed of .pipe() with sockets
|
||||
|
||||
var common = require('../common.js');
|
||||
var PORT = common.PORT;
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
len: [102400, 1024 * 1024 * 16],
|
||||
type: ['utf', 'asc', 'buf'],
|
||||
dur: [5],
|
||||
});
|
||||
|
||||
var dur;
|
||||
var len;
|
||||
var type;
|
||||
var chunk;
|
||||
var encoding;
|
||||
|
||||
function main(conf) {
|
||||
dur = +conf.dur;
|
||||
len = +conf.len;
|
||||
type = conf.type;
|
||||
|
||||
switch (type) {
|
||||
case 'buf':
|
||||
chunk = new Buffer(len);
|
||||
chunk.fill('x');
|
||||
break;
|
||||
case 'utf':
|
||||
encoding = 'utf8';
|
||||
chunk = new Array(len / 2 + 1).join('ü');
|
||||
break;
|
||||
case 'asc':
|
||||
encoding = 'ascii';
|
||||
chunk = new Array(len + 1).join('x');
|
||||
break;
|
||||
default:
|
||||
throw new Error('invalid type: ' + type);
|
||||
break;
|
||||
}
|
||||
|
||||
server();
|
||||
}
|
||||
|
||||
var net = require('net');
|
||||
|
||||
function Writer() {
|
||||
this.received = 0;
|
||||
this.writable = true;
|
||||
}
|
||||
|
||||
Writer.prototype.write = function(chunk, encoding, cb) {
|
||||
this.received += chunk.length;
|
||||
|
||||
if (typeof encoding === 'function')
|
||||
encoding();
|
||||
else if (typeof cb === 'function')
|
||||
cb();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// doesn't matter, never emits anything.
|
||||
Writer.prototype.on = function() {};
|
||||
Writer.prototype.once = function() {};
|
||||
Writer.prototype.emit = function() {};
|
||||
|
||||
|
||||
function Reader() {
|
||||
this.flow = this.flow.bind(this);
|
||||
this.readable = true;
|
||||
}
|
||||
|
||||
Reader.prototype.pipe = function(dest) {
|
||||
this.dest = dest;
|
||||
this.flow();
|
||||
return dest;
|
||||
};
|
||||
|
||||
Reader.prototype.flow = function() {
|
||||
var dest = this.dest;
|
||||
var res = dest.write(chunk, encoding);
|
||||
if (!res)
|
||||
dest.once('drain', this.flow);
|
||||
else
|
||||
process.nextTick(this.flow);
|
||||
};
|
||||
|
||||
|
||||
function server() {
|
||||
var reader = new Reader();
|
||||
var writer = new Writer();
|
||||
|
||||
// the actual benchmark.
|
||||
var server = net.createServer(function(socket) {
|
||||
socket.pipe(socket);
|
||||
});
|
||||
|
||||
server.listen(PORT, function() {
|
||||
var socket = net.connect(PORT);
|
||||
socket.on('connect', function() {
|
||||
bench.start();
|
||||
|
||||
reader.pipe(socket);
|
||||
socket.pipe(writer);
|
||||
|
||||
setTimeout(function() {
|
||||
// multiply by 2 since we're sending it first one way
|
||||
// then then back again.
|
||||
var bytes = writer.received * 2;
|
||||
var gbits = (bytes * 8) / (1024 * 1024 * 1024);
|
||||
bench.end(gbits);
|
||||
}, dur * 1000);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
// test the speed of .pipe() with sockets
|
||||
|
||||
var common = require('../common.js');
|
||||
var PORT = common.PORT;
|
||||
|
||||
var bench = common.createBenchmark(main, {
|
||||
len: [102400, 1024 * 1024 * 16],
|
||||
type: ['utf', 'asc', 'buf'],
|
||||
dur: [5]
|
||||
});
|
||||
|
||||
var dur;
|
||||
var len;
|
||||
var type;
|
||||
var chunk;
|
||||
var encoding;
|
||||
|
||||
function main(conf) {
|
||||
dur = +conf.dur;
|
||||
len = +conf.len;
|
||||
type = conf.type;
|
||||
|
||||
switch (type) {
|
||||
case 'buf':
|
||||
chunk = new Buffer(len);
|
||||
chunk.fill('x');
|
||||
break;
|
||||
case 'utf':
|
||||
encoding = 'utf8';
|
||||
chunk = new Array(len / 2 + 1).join('ü');
|
||||
break;
|
||||
case 'asc':
|
||||
encoding = 'ascii';
|
||||
chunk = new Array(len + 1).join('x');
|
||||
break;
|
||||
default:
|
||||
throw new Error('invalid type: ' + type);
|
||||
break;
|
||||
}
|
||||
|
||||
server();
|
||||
}
|
||||
|
||||
var net = require('net');
|
||||
|
||||
function Writer() {
|
||||
this.received = 0;
|
||||
this.writable = true;
|
||||
}
|
||||
|
||||
Writer.prototype.write = function(chunk, encoding, cb) {
|
||||
this.received += chunk.length;
|
||||
|
||||
if (typeof encoding === 'function')
|
||||
encoding();
|
||||
else if (typeof cb === 'function')
|
||||
cb();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// doesn't matter, never emits anything.
|
||||
Writer.prototype.on = function() {};
|
||||
Writer.prototype.once = function() {};
|
||||
Writer.prototype.emit = function() {};
|
||||
|
||||
|
||||
function Reader() {
|
||||
this.flow = this.flow.bind(this);
|
||||
this.readable = true;
|
||||
}
|
||||
|
||||
Reader.prototype.pipe = function(dest) {
|
||||
this.dest = dest;
|
||||
this.flow();
|
||||
return dest;
|
||||
};
|
||||
|
||||
Reader.prototype.flow = function() {
|
||||
var dest = this.dest;
|
||||
var res = dest.write(chunk, encoding);
|
||||
if (!res)
|
||||
dest.once('drain', this.flow);
|
||||
else
|
||||
process.nextTick(this.flow);
|
||||
};
|
||||
|
||||
|
||||
function server() {
|
||||
var reader = new Reader();
|
||||
var writer = new Writer();
|
||||
|
||||
// the actual benchmark.
|
||||
var server = net.createServer(function(socket) {
|
||||
reader.pipe(socket);
|
||||
});
|
||||
|
||||
server.listen(PORT, function() {
|
||||
var socket = net.connect(PORT);
|
||||
socket.on('connect', function() {
|
||||
bench.start();
|
||||
|
||||
socket.pipe(writer);
|
||||
|
||||
setTimeout(function() {
|
||||
var bytes = writer.received;
|
||||
var gbits = (bytes * 8) / (1024 * 1024 * 1024);
|
||||
bench.end(gbits);
|
||||
}, dur * 1000);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
// In this benchmark, we connect a client to the server, and write
|
||||
// as many bytes as we can in the specified time (default = 10s)
|
||||
|
||||
var common = require('../common.js');
|
||||
var util = require('util');
|
||||
|
||||
// if there are --dur=N and --len=N args, then
|
||||
// run the function with those settings.
|
||||
// if not, then queue up a bunch of child processes.
|
||||
var bench = common.createBenchmark(main, {
|
||||
len: [102400, 1024 * 1024 * 16],
|
||||
type: ['utf', 'asc', 'buf'],
|
||||
dur: [5]
|
||||
});
|
||||
|
||||
var TCP = process.binding('tcp_wrap').TCP;
|
||||
var PORT = common.PORT;
|
||||
|
||||
var dur;
|
||||
var len;
|
||||
var type;
|
||||
|
||||
function main(conf) {
|
||||
dur = +conf.dur;
|
||||
len = +conf.len;
|
||||
type = conf.type;
|
||||
server();
|
||||
}
|
||||
|
||||
|
||||
function fail(err, syscall) {
|
||||
throw util._errnoException(err, syscall);
|
||||
}
|
||||
|
||||
function server() {
|
||||
var serverHandle = new TCP();
|
||||
var err = serverHandle.bind('127.0.0.1', PORT);
|
||||
if (err)
|
||||
fail(err, 'bind');
|
||||
|
||||
err = serverHandle.listen(511);
|
||||
if (err)
|
||||
fail(err, 'listen');
|
||||
|
||||
serverHandle.onconnection = function(err, clientHandle) {
|
||||
if (err)
|
||||
fail(err, 'connect');
|
||||
|
||||
// the meat of the benchmark is right here:
|
||||
bench.start();
|
||||
var bytes = 0;
|
||||
|
||||
setTimeout(function() {
|
||||
// report in Gb/sec
|
||||
bench.end((bytes * 8) / (1024 * 1024 * 1024));
|
||||
}, dur * 1000);
|
||||
|
||||
clientHandle.onread = function(nread, buffer) {
|
||||
// we're not expecting to ever get an EOF from the client.
|
||||
// just lots of data forever.
|
||||
if (nread < 0)
|
||||
fail(nread, 'read');
|
||||
|
||||
// don't slice the buffer. the point of this is to isolate, not
|
||||
// simulate real traffic.
|
||||
bytes += buffer.length;
|
||||
};
|
||||
|
||||
clientHandle.readStart();
|
||||
};
|
||||
|
||||
client();
|
||||
}
|
||||
|
||||
function client() {
|
||||
var chunk;
|
||||
switch (type) {
|
||||
case 'buf':
|
||||
chunk = new Buffer(len);
|
||||
chunk.fill('x');
|
||||
break;
|
||||
case 'utf':
|
||||
chunk = new Array(len / 2 + 1).join('ü');
|
||||
break;
|
||||
case 'asc':
|
||||
chunk = new Array(len + 1).join('x');
|
||||
break;
|
||||
default:
|
||||
throw new Error('invalid type: ' + type);
|
||||
break;
|
||||
}
|
||||
|
||||
var clientHandle = new TCP();
|
||||
var connectReq = {};
|
||||
var err = clientHandle.connect(connectReq, '127.0.0.1', PORT);
|
||||
|
||||
if (err)
|
||||
fail(err, 'connect');
|
||||
|
||||
clientHandle.readStart();
|
||||
|
||||
connectReq.oncomplete = function(err) {
|
||||
if (err)
|
||||
fail(err, 'connect');
|
||||
|
||||
while (clientHandle.writeQueueSize === 0)
|
||||
write();
|
||||
};
|
||||
|
||||
function write() {
|
||||
var writeReq = { oncomplete: afterWrite };
|
||||
var err;
|
||||
switch (type) {
|
||||
case 'buf':
|
||||
err = clientHandle.writeBuffer(writeReq, chunk);
|
||||
break;
|
||||
case 'utf':
|
||||
err = clientHandle.writeUtf8String(writeReq, chunk);
|
||||
break;
|
||||
case 'asc':
|
||||
err = clientHandle.writeAsciiString(writeReq, chunk);
|
||||
break;
|
||||
}
|
||||
|
||||
if (err)
|
||||
fail(err, 'write');
|
||||
}
|
||||
|
||||
function afterWrite(err, handle, req) {
|
||||
if (err)
|
||||
fail(err, 'write');
|
||||
|
||||
while (clientHandle.writeQueueSize === 0)
|
||||
write();
|
||||
}
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
// In this benchmark, we connect a client to the server, and write
|
||||
// as many bytes as we can in the specified time (default = 10s)
|
||||
|
||||
var common = require('../common.js');
|
||||
var util = require('util');
|
||||
|
||||
// if there are --dur=N and --len=N args, then
|
||||
// run the function with those settings.
|
||||
// if not, then queue up a bunch of child processes.
|
||||
var bench = common.createBenchmark(main, {
|
||||
len: [102400, 1024 * 1024 * 16],
|
||||
type: ['utf', 'asc', 'buf'],
|
||||
dur: [5]
|
||||
});
|
||||
|
||||
var TCP = process.binding('tcp_wrap').TCP;
|
||||
var PORT = common.PORT;
|
||||
|
||||
var dur;
|
||||
var len;
|
||||
var type;
|
||||
|
||||
function main(conf) {
|
||||
dur = +conf.dur;
|
||||
len = +conf.len;
|
||||
type = conf.type;
|
||||
server();
|
||||
}
|
||||
|
||||
function fail(err, syscall) {
|
||||
throw util._errnoException(err, syscall);
|
||||
}
|
||||
|
||||
function server() {
|
||||
var serverHandle = new TCP();
|
||||
var err = serverHandle.bind('127.0.0.1', PORT);
|
||||
if (err)
|
||||
fail(err, 'bind');
|
||||
|
||||
err = serverHandle.listen(511);
|
||||
if (err)
|
||||
fail(err, 'listen');
|
||||
|
||||
serverHandle.onconnection = function(err, clientHandle) {
|
||||
if (err)
|
||||
fail(err, 'connect');
|
||||
|
||||
clientHandle.onread = function(nread, buffer) {
|
||||
// we're not expecting to ever get an EOF from the client.
|
||||
// just lots of data forever.
|
||||
if (nread < 0)
|
||||
fail(nread, 'read');
|
||||
|
||||
var writeReq = { async: false };
|
||||
err = clientHandle.writeBuffer(writeReq, buffer);
|
||||
|
||||
if (err)
|
||||
fail(err, 'write');
|
||||
|
||||
writeReq.oncomplete = function(status, handle, req) {
|
||||
if (status)
|
||||
fail(err, 'write');
|
||||
};
|
||||
};
|
||||
|
||||
clientHandle.readStart();
|
||||
};
|
||||
|
||||
client();
|
||||
}
|
||||
|
||||
function client() {
|
||||
var chunk;
|
||||
switch (type) {
|
||||
case 'buf':
|
||||
chunk = new Buffer(len);
|
||||
chunk.fill('x');
|
||||
break;
|
||||
case 'utf':
|
||||
chunk = new Array(len / 2 + 1).join('ü');
|
||||
break;
|
||||
case 'asc':
|
||||
chunk = new Array(len + 1).join('x');
|
||||
break;
|
||||
default:
|
||||
throw new Error('invalid type: ' + type);
|
||||
break;
|
||||
}
|
||||
|
||||
var clientHandle = new TCP();
|
||||
var connectReq = {};
|
||||
var err = clientHandle.connect(connectReq, '127.0.0.1', PORT);
|
||||
var bytes = 0;
|
||||
|
||||
if (err)
|
||||
fail(err, 'connect');
|
||||
|
||||
clientHandle.readStart();
|
||||
|
||||
clientHandle.onread = function(nread, buffer) {
|
||||
if (nread < 0)
|
||||
fail(nread, 'read');
|
||||
|
||||
bytes += buffer.length;
|
||||
};
|
||||
|
||||
connectReq.oncomplete = function(err) {
|
||||
if (err)
|
||||
fail(err, 'connect');
|
||||
|
||||
bench.start();
|
||||
|
||||
setTimeout(function() {
|
||||
// multiply by 2 since we're sending it first one way
|
||||
// then then back again.
|
||||
bench.end(2 * (bytes * 8) / (1024 * 1024 * 1024));
|
||||
}, dur * 1000);
|
||||
|
||||
while (clientHandle.writeQueueSize === 0)
|
||||
write();
|
||||
};
|
||||
|
||||
function write() {
|
||||
var writeReq = { oncomplete: afterWrite };
|
||||
var err;
|
||||
switch (type) {
|
||||
case 'buf':
|
||||
err = clientHandle.writeBuffer(writeReq, chunk);
|
||||
break;
|
||||
case 'utf':
|
||||
err = clientHandle.writeUtf8String(writeReq, chunk);
|
||||
break;
|
||||
case 'asc':
|
||||
err = clientHandle.writeAsciiString(writeReq, chunk);
|
||||
break;
|
||||
}
|
||||
|
||||
if (err)
|
||||
fail(err, 'write');
|
||||
}
|
||||
|
||||
function afterWrite(err, handle, req) {
|
||||
if (err)
|
||||
fail(err, 'write');
|
||||
|
||||
while (clientHandle.writeQueueSize === 0)
|
||||
write();
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
// In this benchmark, we connect a client to the server, and write
|
||||
// as many bytes as we can in the specified time (default = 10s)
|
||||
|
||||
var common = require('../common.js');
|
||||
var util = require('util');
|
||||
|
||||
// if there are dur=N and len=N args, then
|
||||
// run the function with those settings.
|
||||
// if not, then queue up a bunch of child processes.
|
||||
var bench = common.createBenchmark(main, {
|
||||
len: [102400, 1024 * 1024 * 16],
|
||||
type: ['utf', 'asc', 'buf'],
|
||||
dur: [5]
|
||||
});
|
||||
|
||||
var TCP = process.binding('tcp_wrap').TCP;
|
||||
var PORT = common.PORT;
|
||||
|
||||
var dur;
|
||||
var len;
|
||||
var type;
|
||||
|
||||
function main(conf) {
|
||||
dur = +conf.dur;
|
||||
len = +conf.len;
|
||||
type = conf.type;
|
||||
server();
|
||||
}
|
||||
|
||||
function fail(err, syscall) {
|
||||
throw util._errnoException(err, syscall);
|
||||
}
|
||||
|
||||
function server() {
|
||||
var serverHandle = new TCP();
|
||||
var err = serverHandle.bind('127.0.0.1', PORT);
|
||||
if (err)
|
||||
fail(err, 'bind');
|
||||
|
||||
err = serverHandle.listen(511);
|
||||
if (err)
|
||||
fail(err, 'listen');
|
||||
|
||||
serverHandle.onconnection = function(err, clientHandle) {
|
||||
if (err)
|
||||
fail(err, 'connect');
|
||||
|
||||
var chunk;
|
||||
switch (type) {
|
||||
case 'buf':
|
||||
chunk = new Buffer(len);
|
||||
chunk.fill('x');
|
||||
break;
|
||||
case 'utf':
|
||||
chunk = new Array(len / 2 + 1).join('ü');
|
||||
break;
|
||||
case 'asc':
|
||||
chunk = new Array(len + 1).join('x');
|
||||
break;
|
||||
default:
|
||||
throw new Error('invalid type: ' + type);
|
||||
break;
|
||||
}
|
||||
|
||||
clientHandle.readStart();
|
||||
|
||||
while (clientHandle.writeQueueSize === 0)
|
||||
write();
|
||||
|
||||
function write() {
|
||||
var writeReq = { async: false, oncomplete: afterWrite };
|
||||
var err;
|
||||
switch (type) {
|
||||
case 'buf':
|
||||
err = clientHandle.writeBuffer(writeReq, chunk);
|
||||
break;
|
||||
case 'utf':
|
||||
err = clientHandle.writeUtf8String(writeReq, chunk);
|
||||
break;
|
||||
case 'asc':
|
||||
err = clientHandle.writeAsciiString(writeReq, chunk);
|
||||
break;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
fail(err, 'write');
|
||||
} else if (!writeReq.async) {
|
||||
process.nextTick(function() {
|
||||
afterWrite(null, clientHandle, writeReq);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function afterWrite(err, handle, req) {
|
||||
if (err)
|
||||
fail(err, 'write');
|
||||
|
||||
while (clientHandle.writeQueueSize === 0)
|
||||
write();
|
||||
}
|
||||
};
|
||||
|
||||
client();
|
||||
}
|
||||
|
||||
function client() {
|
||||
var clientHandle = new TCP();
|
||||
var connectReq = {};
|
||||
var err = clientHandle.connect(connectReq, '127.0.0.1', PORT);
|
||||
|
||||
if (err)
|
||||
fail(err, 'connect');
|
||||
|
||||
connectReq.oncomplete = function() {
|
||||
var bytes = 0;
|
||||
clientHandle.onread = function(nread, buffer) {
|
||||
// we're not expecting to ever get an EOF from the client.
|
||||
// just lots of data forever.
|
||||
if (nread < 0)
|
||||
fail(nread, 'read');
|
||||
|
||||
// don't slice the buffer. the point of this is to isolate, not
|
||||
// simulate real traffic.
|
||||
bytes += buffer.length;
|
||||
};
|
||||
|
||||
clientHandle.readStart();
|
||||
|
||||
// the meat of the benchmark is right here:
|
||||
bench.start();
|
||||
|
||||
setTimeout(function() {
|
||||
// report in Gb/sec
|
||||
bench.end((bytes * 8) / (1024 * 1024 * 1024));
|
||||
}, dur * 1000);
|
||||
};
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
#!/usr/bin/env Rscript
|
||||
|
||||
# To use this script you'll need to install R: http://www.r-project.org/
|
||||
# and a library for R called ggplot2
|
||||
# Which can be done by starting R and typing install.packages("ggplot2")
|
||||
# like this:
|
||||
#
|
||||
# shell% R
|
||||
# R version 2.11.0 beta (2010-04-12 r51689)
|
||||
# > install.packages("ggplot2")
|
||||
# (follow prompt)
|
||||
#
|
||||
# Then you can try this script by providing a full path to .data file
|
||||
# outputed from 'make bench'
|
||||
#
|
||||
# > cd ~/src/node
|
||||
# > make bench
|
||||
# ...
|
||||
# > ./benchmark/plot.R .benchmark_reports/ab-hello-world-buffer-1024/ff456b38862de3fd0118c6ac6b3f46edb1fbb87f/20101013162056.data
|
||||
#
|
||||
# This will generate a PNG file which you can view
|
||||
#
|
||||
#
|
||||
# Hopefully these steps will be automated in the future.
|
||||
|
||||
|
||||
|
||||
library(ggplot2)
|
||||
|
||||
args <- commandArgs(TRUE)
|
||||
|
||||
ab.load <- function (filename, name) {
|
||||
raw <- data.frame(read.csv(filename, sep="\t", header=T), server=name)
|
||||
raw <- data.frame(raw, time=raw$seconds-min(raw$seconds))
|
||||
raw <- data.frame(raw, time_s=raw$time/1000000)
|
||||
raw
|
||||
}
|
||||
|
||||
#ab.tsPoint <- function (d) {
|
||||
# qplot(time_s, ttime, data=d, facets=server~.,
|
||||
# geom="point", alpha=I(1/15), ylab="response time (ms)",
|
||||
# xlab="time (s)", main="c=30, res=26kb",
|
||||
# ylim=c(0,100))
|
||||
#}
|
||||
#
|
||||
#ab.tsLine <- function (d) {
|
||||
# qplot(time_s, ttime, data=d, facets=server~.,
|
||||
# geom="line", ylab="response time (ms)",
|
||||
# xlab="time (s)", main="c=30, res=26kb",
|
||||
# ylim=c(0,100))
|
||||
#}
|
||||
|
||||
|
||||
filename <- args[0:1]
|
||||
data <- ab.load(filename, "node")
|
||||
|
||||
|
||||
# histogram
|
||||
|
||||
#hist_png_filename <- gsub(".data", "_hist.png", filename)
|
||||
hist_png_filename <- "hist.png"
|
||||
|
||||
png(filename = hist_png_filename, width = 480, height = 380, units = "px")
|
||||
|
||||
qplot(ttime, data=data, geom="histogram",
|
||||
main="xxx",
|
||||
binwidth=1, xlab="response time (ms)",
|
||||
xlim=c(0,100))
|
||||
|
||||
print(hist_png_filename)
|
||||
|
||||
|
||||
|
||||
# time series
|
||||
|
||||
#ts_png_filename <- gsub(".data", "_ts.png", filename)
|
||||
ts_png_filename = "ts.png"
|
||||
|
||||
png(filename = ts_png_filename, width = 480, height = 380, units = "px")
|
||||
|
||||
qplot(time, ttime, data=data, facets=server~.,
|
||||
geom="point", alpha=I(1/15), ylab="response time (ms)",
|
||||
xlab="time (s)", main="xxx",
|
||||
ylim=c(0,100))
|
||||
|
||||
print(ts_png_filename)
|
||||
19
benchmark/process_loop.js
Normal file
19
benchmark/process_loop.js
Normal file
@@ -0,0 +1,19 @@
|
||||
var sys = require("sys"),
|
||||
childProcess = require("child_process");
|
||||
|
||||
function next (i) {
|
||||
if (i <= 0) return;
|
||||
|
||||
var child = childProcess.spawn("echo", ["hello"]);
|
||||
|
||||
child.stdout.addListener("data", function (chunk) {
|
||||
sys.print(chunk);
|
||||
});
|
||||
|
||||
child.addListener("exit", function (code) {
|
||||
if (code != 0) process.exit(-1);
|
||||
next(i - 1);
|
||||
});
|
||||
}
|
||||
|
||||
next(500);
|
||||
@@ -1 +0,0 @@
|
||||
console.log(process.memoryUsage().rss);
|
||||
31
benchmark/run.js
Normal file
31
benchmark/run.js
Normal file
@@ -0,0 +1,31 @@
|
||||
var path = require("path");
|
||||
var sys = require("sys");
|
||||
var childProcess = require("child_process");
|
||||
var benchmarks = [ "timers.js"
|
||||
, "process_loop.js"
|
||||
, "static_http_server.js"
|
||||
];
|
||||
|
||||
var benchmarkDir = path.dirname(__filename);
|
||||
|
||||
function exec (script, callback) {
|
||||
var start = new Date();
|
||||
var child = childProcess.spawn(process.argv[0], [path.join(benchmarkDir, script)]);
|
||||
child.addListener("exit", function (code) {
|
||||
var elapsed = new Date() - start;
|
||||
callback(elapsed, code);
|
||||
});
|
||||
}
|
||||
|
||||
function runNext (i) {
|
||||
if (i >= benchmarks.length) return;
|
||||
sys.print(benchmarks[i] + ": ");
|
||||
exec(benchmarks[i], function (elapsed, code) {
|
||||
if (code != 0) {
|
||||
console.log("ERROR ");
|
||||
}
|
||||
console.log(elapsed);
|
||||
runNext(i+1);
|
||||
});
|
||||
};
|
||||
runNext(0);
|
||||
26
benchmark/startup.js
Normal file
26
benchmark/startup.js
Normal file
@@ -0,0 +1,26 @@
|
||||
var spawn = require('child_process').spawn,
|
||||
path = require('path'),
|
||||
emptyJsFile = path.join(__dirname, '../test/fixtures/semicolon.js'),
|
||||
starts = 100,
|
||||
i = 0,
|
||||
start;
|
||||
|
||||
function startNode() {
|
||||
var node = spawn(process.execPath || process.argv[0], [emptyJsFile]);
|
||||
node.on('exit', function(exitCode) {
|
||||
if (exitCode !== 0) {
|
||||
throw new Error('Error during node startup');
|
||||
}
|
||||
|
||||
i++;
|
||||
if (i < starts) {
|
||||
startNode();
|
||||
} else{
|
||||
var duration = +new Date - start;
|
||||
console.log('Started node %d times in %s ms. %d ms / start.', starts, duration, duration / starts);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
start = +new Date;
|
||||
startNode();
|
||||
@@ -1,44 +1,48 @@
|
||||
var http = require('http');
|
||||
var http = require("http");
|
||||
|
||||
var concurrency = 30;
|
||||
var port = 12346;
|
||||
var n = 700;
|
||||
var n = 7; // several orders of magnitude slower
|
||||
var bytes = 1024*5;
|
||||
|
||||
var requests = 0;
|
||||
var responses = 0;
|
||||
|
||||
var body = '';
|
||||
var body = "";
|
||||
for (var i = 0; i < bytes; i++) {
|
||||
body += 'C';
|
||||
body += "C";
|
||||
}
|
||||
|
||||
var server = http.createServer(function(req, res) {
|
||||
var server = http.createServer(function (req, res) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/plain',
|
||||
'Content-Length': body.length
|
||||
"Content-Type": "text/plain",
|
||||
"Content-Length": body.length
|
||||
});
|
||||
res.end(body);
|
||||
res.write(body);
|
||||
res.close();
|
||||
})
|
||||
server.listen(port);
|
||||
|
||||
server.listen(port, function() {
|
||||
var agent = new http.Agent();
|
||||
agent.maxSockets = concurrency;
|
||||
function responseListener (res) {
|
||||
res.addListener("end", function () {
|
||||
if (requests < n) {
|
||||
var req = res.client.request("/");
|
||||
req.addListener('response', responseListener);
|
||||
req.close();
|
||||
requests++;
|
||||
}
|
||||
|
||||
for (var i = 0; i < n; i++) {
|
||||
var req = http.get({
|
||||
port: port,
|
||||
path: '/',
|
||||
agent: agent
|
||||
}, function(res) {
|
||||
res.resume();
|
||||
res.on('end', function() {
|
||||
if (++responses === n) {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
req.id = i;
|
||||
requests++;
|
||||
}
|
||||
});
|
||||
if (++responses == n) {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (var i = 0; i < concurrency; i++) {
|
||||
var client = http.createClient(port);
|
||||
client.id = i;
|
||||
var req = client.request("/");
|
||||
req.addListener('response', responseListener);
|
||||
req.close();
|
||||
requests++;
|
||||
}
|
||||
|
||||
6
benchmark/string_creation.js
Normal file
6
benchmark/string_creation.js
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
for (var i = 0; i < 9e7; i++) {
|
||||
s = '01234567890';
|
||||
s[1] = "a";
|
||||
}
|
||||
5
benchmark/timers.js
Normal file
5
benchmark/timers.js
Normal file
@@ -0,0 +1,5 @@
|
||||
function next (i) {
|
||||
if (i <= 0) return;
|
||||
setTimeout(function () { next(i-1); }, 1);
|
||||
}
|
||||
next(700);
|
||||
@@ -1,75 +0,0 @@
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
dur: [5],
|
||||
type: ['buf', 'asc', 'utf'],
|
||||
size: [2, 1024, 1024 * 1024]
|
||||
});
|
||||
|
||||
var dur, type, encoding, size;
|
||||
var server;
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var cert_dir = path.resolve(__dirname, '../../test/fixtures');
|
||||
var options;
|
||||
var tls = require('tls');
|
||||
|
||||
function main(conf) {
|
||||
dur = +conf.dur;
|
||||
type = conf.type;
|
||||
size = +conf.size;
|
||||
|
||||
var chunk;
|
||||
switch (type) {
|
||||
case 'buf':
|
||||
chunk = new Buffer(size);
|
||||
chunk.fill('b');
|
||||
break;
|
||||
case 'asc':
|
||||
chunk = new Array(size + 1).join('a');
|
||||
encoding = 'ascii';
|
||||
break;
|
||||
case 'utf':
|
||||
chunk = new Array(size/2 + 1).join('ü');
|
||||
encoding = 'utf8';
|
||||
break;
|
||||
default:
|
||||
throw new Error('invalid type');
|
||||
}
|
||||
|
||||
options = { key: fs.readFileSync(cert_dir + '/test_key.pem'),
|
||||
cert: fs.readFileSync(cert_dir + '/test_cert.pem'),
|
||||
ca: [ fs.readFileSync(cert_dir + '/test_ca.pem') ],
|
||||
ciphers: 'AES256-GCM-SHA384' };
|
||||
|
||||
server = tls.createServer(options, onConnection);
|
||||
setTimeout(done, dur * 1000);
|
||||
server.listen(common.PORT, function() {
|
||||
var opt = { port: common.PORT, rejectUnauthorized: false };
|
||||
var conn = tls.connect(opt, function() {
|
||||
bench.start();
|
||||
conn.on('drain', write);
|
||||
write();
|
||||
});
|
||||
|
||||
function write() {
|
||||
var i = 0;
|
||||
while (false !== conn.write(chunk, encoding));
|
||||
}
|
||||
});
|
||||
|
||||
var received = 0;
|
||||
function onConnection(conn) {
|
||||
conn.on('data', function(chunk) {
|
||||
received += chunk.length;
|
||||
});
|
||||
}
|
||||
|
||||
function done() {
|
||||
var mbits = (received * 8) / (1024 * 1024);
|
||||
bench.end(mbits);
|
||||
conn.destroy();
|
||||
server.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
var assert = require('assert'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
tls = require('tls');
|
||||
|
||||
var common = require('../common.js');
|
||||
var bench = common.createBenchmark(main, {
|
||||
concurrency: [1, 10],
|
||||
dur: [5]
|
||||
});
|
||||
|
||||
var clientConn = 0;
|
||||
var serverConn = 0;
|
||||
var server;
|
||||
var dur;
|
||||
var concurrency;
|
||||
var running = true;
|
||||
|
||||
function main(conf) {
|
||||
dur = +conf.dur;
|
||||
concurrency = +conf.concurrency;
|
||||
|
||||
var cert_dir = path.resolve(__dirname, '../../test/fixtures'),
|
||||
options = { key: fs.readFileSync(cert_dir + '/test_key.pem'),
|
||||
cert: fs.readFileSync(cert_dir + '/test_cert.pem'),
|
||||
ca: [ fs.readFileSync(cert_dir + '/test_ca.pem') ],
|
||||
ciphers: 'AES256-GCM-SHA384' };
|
||||
|
||||
server = tls.createServer(options, onConnection);
|
||||
server.listen(common.PORT, onListening);
|
||||
}
|
||||
|
||||
function onListening() {
|
||||
setTimeout(done, dur * 1000);
|
||||
bench.start();
|
||||
for (var i = 0; i < concurrency; i++)
|
||||
makeConnection();
|
||||
}
|
||||
|
||||
function onConnection(conn) {
|
||||
serverConn++;
|
||||
}
|
||||
|
||||
function makeConnection() {
|
||||
var conn = tls.connect({ port: common.PORT,
|
||||
rejectUnauthorized: false }, function() {
|
||||
clientConn++;
|
||||
conn.on('error', function(er) {
|
||||
console.error('client error', er);
|
||||
throw er;
|
||||
});
|
||||
conn.end();
|
||||
if (running) makeConnection();
|
||||
});
|
||||
}
|
||||
|
||||
function done() {
|
||||
running = false;
|
||||
// it's only an established connection if they both saw it.
|
||||
// because we destroy the server somewhat abruptly, these
|
||||
// don't always match. Generally, serverConn will be
|
||||
// the smaller number, but take the min just to be sure.
|
||||
bench.end(Math.min(serverConn, clientConn));
|
||||
}
|
||||
8
bin/node-repl
Executable file
8
bin/node-repl
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
console.log("Type '.help' for options.");
|
||||
console.log("(The REPL can also be started by typing 'node' without arguments)");
|
||||
|
||||
require('repl').start();
|
||||
|
||||
// vim:ft=javascript
|
||||
17
bin/node-waf
Executable file
17
bin/node-waf
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python
|
||||
import os, sys
|
||||
|
||||
|
||||
join = os.path.join
|
||||
bindir = os.path.dirname(os.path.realpath(__file__))
|
||||
prefix = join(bindir, "..")
|
||||
wafdir = join(prefix, "lib", "node")
|
||||
|
||||
w = join(wafdir, 'wafadmin')
|
||||
t = join(w, 'Tools')
|
||||
sys.path = [w, t] + sys.path
|
||||
|
||||
import Scripting
|
||||
VERSION="1.5.16"
|
||||
Scripting.prepare(t, os.getcwd(), VERSION, wafdir)
|
||||
sys.exit(0)
|
||||
260
common.gypi
260
common.gypi
@@ -1,260 +0,0 @@
|
||||
{
|
||||
'variables': {
|
||||
'werror': '', # Turn off -Werror in V8 build.
|
||||
'visibility%': 'hidden', # V8's visibility setting
|
||||
'target_arch%': 'ia32', # set v8's target architecture
|
||||
'host_arch%': 'ia32', # set v8's host architecture
|
||||
'want_separate_host_toolset%': 0, # V8 should not build target and host
|
||||
'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
|
||||
'component%': 'static_library', # NB. these names match with what V8 expects
|
||||
'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way
|
||||
'gcc_version%': 'unknown',
|
||||
'clang%': 0,
|
||||
'python%': 'python',
|
||||
|
||||
# Enable disassembler for `--print-code` v8 options
|
||||
'v8_enable_disassembler': 1,
|
||||
|
||||
# Enable V8's post-mortem debugging only on unix flavors.
|
||||
'conditions': [
|
||||
['OS == "win"', {
|
||||
'os_posix': 0,
|
||||
'v8_postmortem_support': 'false'
|
||||
}, {
|
||||
'os_posix': 1,
|
||||
'v8_postmortem_support': 'true'
|
||||
}],
|
||||
['GENERATOR == "ninja" or OS== "mac"', {
|
||||
'OBJ_DIR': '<(PRODUCT_DIR)/obj',
|
||||
'V8_BASE': '<(PRODUCT_DIR)/libv8_base.a',
|
||||
}, {
|
||||
'OBJ_DIR': '<(PRODUCT_DIR)/obj.target',
|
||||
'V8_BASE': '<(PRODUCT_DIR)/obj.target/deps/v8/tools/gyp/libv8_base.a',
|
||||
}],
|
||||
],
|
||||
},
|
||||
|
||||
'target_defaults': {
|
||||
'default_configuration': 'Release',
|
||||
'configurations': {
|
||||
'Debug': {
|
||||
'variables': {
|
||||
'v8_enable_handle_zapping%': 1,
|
||||
},
|
||||
'defines': [ 'DEBUG', '_DEBUG' ],
|
||||
'cflags': [ '-g', '-O0' ],
|
||||
'conditions': [
|
||||
['target_arch=="x64"', {
|
||||
'msvs_configuration_platform': 'x64',
|
||||
}],
|
||||
],
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'RuntimeLibrary': 1, # static debug
|
||||
'Optimization': 0, # /Od, no optimization
|
||||
'MinimalRebuild': 'false',
|
||||
'OmitFramePointers': 'false',
|
||||
'BasicRuntimeChecks': 3, # /RTC1
|
||||
},
|
||||
'VCLinkerTool': {
|
||||
'LinkIncremental': 2, # enable incremental linking
|
||||
},
|
||||
},
|
||||
'xcode_settings': {
|
||||
'GCC_OPTIMIZATION_LEVEL': '0', # stop gyp from defaulting to -Os
|
||||
},
|
||||
},
|
||||
'Release': {
|
||||
'variables': {
|
||||
'v8_enable_handle_zapping%': 0,
|
||||
},
|
||||
'cflags': [ '-O3', '-ffunction-sections', '-fdata-sections' ],
|
||||
'conditions': [
|
||||
['target_arch=="x64"', {
|
||||
'msvs_configuration_platform': 'x64',
|
||||
}],
|
||||
['OS=="solaris"', {
|
||||
# pull in V8's postmortem metadata
|
||||
'ldflags': [ '-Wl,-z,allextract' ]
|
||||
}],
|
||||
['clang == 0 and gcc_version >= 40', {
|
||||
'cflags': [ '-fno-tree-vrp' ], # Work around compiler bug.
|
||||
}],
|
||||
['clang == 0 and gcc_version <= 44', {
|
||||
'cflags': [ '-fno-tree-sink' ], # Work around compiler bug.
|
||||
}],
|
||||
['OS!="mac" and OS!="win"', {
|
||||
'cflags': [ '-fno-omit-frame-pointer' ],
|
||||
}],
|
||||
],
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'RuntimeLibrary': 0, # static release
|
||||
'Optimization': 3, # /Ox, full optimization
|
||||
'FavorSizeOrSpeed': 1, # /Ot, favour speed over size
|
||||
'InlineFunctionExpansion': 2, # /Ob2, inline anything eligible
|
||||
'WholeProgramOptimization': 'true', # /GL, whole program optimization, needed for LTCG
|
||||
'OmitFramePointers': 'true',
|
||||
'EnableFunctionLevelLinking': 'true',
|
||||
'EnableIntrinsicFunctions': 'true',
|
||||
'RuntimeTypeInfo': 'false',
|
||||
'ExceptionHandling': '0',
|
||||
'AdditionalOptions': [
|
||||
'/MP', # compile across multiple CPUs
|
||||
],
|
||||
},
|
||||
'VCLibrarianTool': {
|
||||
'AdditionalOptions': [
|
||||
'/LTCG', # link time code generation
|
||||
],
|
||||
},
|
||||
'VCLinkerTool': {
|
||||
'LinkTimeCodeGeneration': 1, # link-time code generation
|
||||
'OptimizeReferences': 2, # /OPT:REF
|
||||
'EnableCOMDATFolding': 2, # /OPT:ICF
|
||||
'LinkIncremental': 1, # disable incremental linking
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
# Forcibly disable -Werror. We support a wide range of compilers, it's
|
||||
# simply not feasible to squelch all warnings, never mind that the
|
||||
# libraries in deps/ are not under our control.
|
||||
'cflags!': ['-Werror'],
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'StringPooling': 'true', # pool string literals
|
||||
'DebugInformationFormat': 3, # Generate a PDB
|
||||
'WarningLevel': 3,
|
||||
'BufferSecurityCheck': 'true',
|
||||
'ExceptionHandling': 1, # /EHsc
|
||||
'SuppressStartupBanner': 'true',
|
||||
'WarnAsError': 'false',
|
||||
},
|
||||
'VCLibrarianTool': {
|
||||
},
|
||||
'VCLinkerTool': {
|
||||
'conditions': [
|
||||
['target_arch=="ia32"', {
|
||||
'TargetMachine' : 1, # /MACHINE:X86
|
||||
'target_conditions': [
|
||||
['_type=="executable"', {
|
||||
'AdditionalOptions': [ '/SubSystem:Console,"5.01"' ],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
['target_arch=="x64"', {
|
||||
'TargetMachine' : 17, # /MACHINE:AMD64
|
||||
'target_conditions': [
|
||||
['_type=="executable"', {
|
||||
'AdditionalOptions': [ '/SubSystem:Console,"5.02"' ],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
],
|
||||
'GenerateDebugInformation': 'true',
|
||||
'RandomizedBaseAddress': 2, # enable ASLR
|
||||
'DataExecutionPrevention': 2, # enable DEP
|
||||
'AllowIsolation': 'true',
|
||||
'SuppressStartupBanner': 'true',
|
||||
},
|
||||
},
|
||||
'msvs_disabled_warnings': [4351, 4355, 4800],
|
||||
'conditions': [
|
||||
['OS == "win"', {
|
||||
'msvs_cygwin_shell': 0, # prevent actions from trying to use cygwin
|
||||
'defines': [
|
||||
'WIN32',
|
||||
# we don't really want VC++ warning us about
|
||||
# how dangerous C functions are...
|
||||
'_CRT_SECURE_NO_DEPRECATE',
|
||||
# ... or that C implementations shouldn't use
|
||||
# POSIX names
|
||||
'_CRT_NONSTDC_NO_DEPRECATE',
|
||||
'BUILDING_V8_SHARED=1',
|
||||
'BUILDING_UV_SHARED=1',
|
||||
],
|
||||
}],
|
||||
[ 'OS in "linux freebsd openbsd solaris"', {
|
||||
'cflags': [ '-pthread', ],
|
||||
'ldflags': [ '-pthread' ],
|
||||
}],
|
||||
[ 'OS in "linux freebsd openbsd solaris android"', {
|
||||
'cflags': [ '-Wall', '-Wextra', '-Wno-unused-parameter', ],
|
||||
'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
|
||||
'ldflags': [ '-rdynamic' ],
|
||||
'target_conditions': [
|
||||
['_type=="static_library"', {
|
||||
'standalone_static_library': 1, # disable thin archive which needs binutils >= 2.19
|
||||
}],
|
||||
],
|
||||
'conditions': [
|
||||
[ 'target_arch=="ia32"', {
|
||||
'cflags': [ '-m32' ],
|
||||
'ldflags': [ '-m32' ],
|
||||
}],
|
||||
[ 'target_arch=="x64"', {
|
||||
'cflags': [ '-m64' ],
|
||||
'ldflags': [ '-m64' ],
|
||||
}],
|
||||
[ 'OS=="solaris"', {
|
||||
'cflags': [ '-pthreads' ],
|
||||
'ldflags': [ '-pthreads' ],
|
||||
'cflags!': [ '-pthread' ],
|
||||
'ldflags!': [ '-pthread' ],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
[ 'OS=="android"', {
|
||||
'defines': ['_GLIBCXX_USE_C99_MATH'],
|
||||
'libraries': [ '-llog' ],
|
||||
}],
|
||||
['OS=="mac"', {
|
||||
'defines': ['_DARWIN_USE_64_BIT_INODE=1'],
|
||||
'xcode_settings': {
|
||||
'ALWAYS_SEARCH_USER_PATHS': 'NO',
|
||||
'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks
|
||||
'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic
|
||||
# (Equivalent to -fPIC)
|
||||
'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions
|
||||
'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
|
||||
'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
|
||||
'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
|
||||
'PREBINDING': 'NO', # No -Wl,-prebind
|
||||
'MACOSX_DEPLOYMENT_TARGET': '10.5', # -mmacosx-version-min=10.5
|
||||
'USE_HEADERMAP': 'NO',
|
||||
'OTHER_CFLAGS': [
|
||||
'-fno-strict-aliasing',
|
||||
],
|
||||
'WARNING_CFLAGS': [
|
||||
'-Wall',
|
||||
'-Wendif-labels',
|
||||
'-W',
|
||||
'-Wno-unused-parameter',
|
||||
],
|
||||
},
|
||||
'target_conditions': [
|
||||
['_type!="static_library"', {
|
||||
'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']},
|
||||
}],
|
||||
],
|
||||
'conditions': [
|
||||
['target_arch=="ia32"', {
|
||||
'xcode_settings': {'ARCHS': ['i386']},
|
||||
}],
|
||||
['target_arch=="x64"', {
|
||||
'xcode_settings': {'ARCHS': ['x86_64']},
|
||||
}],
|
||||
],
|
||||
}],
|
||||
['OS=="freebsd" and node_use_dtrace=="true"', {
|
||||
'libraries': [ '-lelf' ],
|
||||
}],
|
||||
['OS=="freebsd"', {
|
||||
'ldflags': [
|
||||
'-Wl,--export-dynamic',
|
||||
],
|
||||
}]
|
||||
],
|
||||
}
|
||||
}
|
||||
37
deps/c-ares/AUTHORS
vendored
Normal file
37
deps/c-ares/AUTHORS
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
c-ares is based on ares, and these are the people that have worked on it since
|
||||
the fork was made:
|
||||
|
||||
Alexander Lazic
|
||||
Alexey Simak
|
||||
Andreas Rieke
|
||||
Ashish Sharma
|
||||
Brad House
|
||||
Brad Spencer
|
||||
Bram Matthys
|
||||
Dan Fandrich
|
||||
Daniel Stenberg
|
||||
Dirk Manske
|
||||
Dominick Meglio
|
||||
Doug Goldstein
|
||||
Duncan Wilcox
|
||||
Eino Tuominen
|
||||
Erik Kline
|
||||
George Neill
|
||||
Gisle Vanem
|
||||
Guilherme Balena Versiani
|
||||
Gunter Knauf
|
||||
Henrik Stoerner
|
||||
James Bursa
|
||||
Michael Wallner
|
||||
Nick Mathewson
|
||||
Phil Blundell
|
||||
Ravi Pratap
|
||||
Robin Cornelius
|
||||
Sebastian at basti79.de
|
||||
Shmulik Regev
|
||||
Steinar H. Gunderson
|
||||
Tofu Linden
|
||||
Vlad Dinulescu
|
||||
William Ahern
|
||||
Yang Tse
|
||||
liren at vivisimo.com
|
||||
1179
deps/c-ares/CHANGES
vendored
Normal file
1179
deps/c-ares/CHANGES
vendored
Normal file
File diff suppressed because it is too large
Load Diff
0
deps/cares/src/NEWS → deps/c-ares/NEWS
vendored
0
deps/cares/src/NEWS → deps/c-ares/NEWS
vendored
60
deps/c-ares/README
vendored
Normal file
60
deps/c-ares/README
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
c-ares
|
||||
======
|
||||
|
||||
This is c-ares, an asynchronous resolver library. It is intended for
|
||||
applications which need to perform DNS queries without blocking, or need to
|
||||
perform multiple DNS queries in parallel. The primary examples of such
|
||||
applications are servers which communicate with multiple clients and programs
|
||||
with graphical user interfaces.
|
||||
|
||||
The full source code is available in the 'c-ares' release archives, and in a
|
||||
git repository: http://github.com/bagder/c-ares
|
||||
|
||||
If you find bugs, correct flaws, have questions or have comments in general in
|
||||
regard to c-ares (or by all means the original ares too), get in touch with us
|
||||
on the c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares
|
||||
|
||||
c-ares is of course distributed under the same MIT-style license as the
|
||||
original ares.
|
||||
|
||||
You'll find all c-ares details and news here:
|
||||
|
||||
http://c-ares.haxx.se/
|
||||
|
||||
|
||||
NOTES FOR C-ARES HACKERS
|
||||
|
||||
The following notes apply to c-ares version 1.7.0 and later.
|
||||
|
||||
* The distributed ares_build.h file is only intended to be used on systems
|
||||
which can not run the also distributed configure script.
|
||||
|
||||
* The distributed ares_build.h file is generated as a copy of ares_build.h.dist
|
||||
when the c-ares source code distribution archive file is originally created.
|
||||
|
||||
* If you check out from git on a non-configure platform, you must run the
|
||||
appropriate buildconf* script to set up ares_build.h and other local files
|
||||
before being able of compiling the library.
|
||||
|
||||
* On systems capable of running the configure script, the configure process
|
||||
will overwrite the distributed ares_build.h file with one that is suitable
|
||||
and specific to the library being configured and built, this new file is
|
||||
generated from the ares_build.h.in template file.
|
||||
|
||||
* If you intend to distribute an already compiled c-ares library you _MUST_
|
||||
also distribute along with it the generated ares_build.h which has been
|
||||
used to compile it. Otherwise the library will be of no use for the users of
|
||||
the library that you have built. It is _your_ responsibility to provide this
|
||||
file. No one at the c-ares project can know how you have built the library.
|
||||
|
||||
* File ares_build.h includes platform and configuration dependent info,
|
||||
and must not be modified by anyone. Configure script generates it for you.
|
||||
|
||||
* We cannot assume anything else but very basic compiler features being
|
||||
present. While c-ares requires an ANSI C compiler to build, some of the
|
||||
earlier ANSI compilers clearly can't deal with some preprocessor operators.
|
||||
|
||||
* Newlines must remain unix-style for older compilers' sake.
|
||||
|
||||
* Comments must be written in the old-style /* unnested C-fashion */
|
||||
|
||||
@@ -40,30 +40,6 @@
|
||||
library version it is using.
|
||||
|
||||
|
||||
How to install using MSVC from the command line
|
||||
-----------------------------------------------
|
||||
|
||||
In order to allow easy usage of c-ares libraries it may be convenient to
|
||||
install c-ares libraries and header files to a common subdirectory tree.
|
||||
|
||||
Once that c-ares libraries have been built using procedure described above,
|
||||
use same command prompt window to define environment variable INSTALL_DIR
|
||||
to designate the top subdirectory where installation of c-ares libraries and
|
||||
header files will be done.
|
||||
|
||||
> set INSTALL_DIR=c:\c-ares
|
||||
|
||||
Afterwards, run following command to actually perform the installation:
|
||||
|
||||
> nmake -f Makefile.msvc install
|
||||
|
||||
Installation procedure will copy c-ares libraries to subdirectory 'lib' and
|
||||
c-ares header files to subdirectory 'include' below the INSTALL_DIR subdir.
|
||||
|
||||
When environment variable INSTALL_DIR is not defined, installation is done
|
||||
to c-ares source folder where Makefile.msvc file is located.
|
||||
|
||||
|
||||
How to build using Visual Studio 6 IDE
|
||||
--------------------------------------
|
||||
|
||||
21
deps/c-ares/README.node
vendored
Normal file
21
deps/c-ares/README.node
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
Library: c-ares, DNS resolver
|
||||
|
||||
Version: 1.7.3 (11 June, 2010)
|
||||
|
||||
Authors: Greg Hudson, Daniel Stenberg
|
||||
|
||||
License: MIT
|
||||
|
||||
Notes:
|
||||
|
||||
Just use waf instead of the autoconf based configure script. Delete most of
|
||||
the documentation and other files distributed with it. To upgrade, run
|
||||
./configure on linux, macintosh, solaris (and other supported platforms) and
|
||||
copy
|
||||
- ares_config.h
|
||||
- ares_setup.h
|
||||
- ares_build.h
|
||||
into the appropriate directory.
|
||||
|
||||
|
||||
|
||||
12
deps/c-ares/RELEASE-NOTES
vendored
Normal file
12
deps/c-ares/RELEASE-NOTES
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
c-ares version 1.7.3
|
||||
|
||||
Fixed:
|
||||
|
||||
o builds on Android
|
||||
o now includes all files necessary to build it (1.7.2 lacked a file)
|
||||
|
||||
Thanks go to these friendly people for their efforts and contributions:
|
||||
|
||||
Yang Tse, Bogdan Vatra
|
||||
|
||||
Have fun!
|
||||
0
deps/cares/src/TODO → deps/c-ares/TODO
vendored
0
deps/cares/src/TODO → deps/c-ares/TODO
vendored
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user