startup-time 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9ba80fb5d1e63389c3ca3b8b3dc3b0a8cc338504f6a23c810d14335e0e044f5
4
- data.tar.gz: 8e199bbea99112e8dc993d6c3500bad99048cb72fd8f6bd96c498da40ee9b20d
3
+ metadata.gz: b4a81d32c87d33dc6e8dd9099982be606ac59256d5968350e109f97979ee96eb
4
+ data.tar.gz: 0200de23b714da4f6d45f4267e563e54217573fb58fbf66bf1d0ca1016eebd63
5
5
  SHA512:
6
- metadata.gz: 9de0b24fbd653e0d52e95b39838d2af9258de9fbd0e2e16f75827413c37d4ed86522da5f74b531fd71404faf9cc1f73d3bfe5afd19ded0be2eb0960b220d297c
7
- data.tar.gz: a2432428c758ccc48fa0e7616c88fa61e0acd73abab6ec4751d4f3cb2cc93f4fe7efed31c58f611c4e6173d2aa993ff13e6053b1559945a34e036d8e92d12de1
6
+ metadata.gz: 49c7f9e3e518859dcd7735bb101f6f4e5f48bf6d5a7da890efaf1951de58c0e89cef93a2f447fa4bc677d4cda2fa2aaf24ae9d58fe09683507a65dd9f6b5ca1c
7
+ data.tar.gz: 9b7dfff84fb1b333aefdd5ff19c176f9e9238754fd52aeac4c9cdf2c18f3fdc5930af7d9ed61ce4fdd2ec44520e15ce8a268a453ed367afd5b4e4d7c4bd60a44
@@ -1,6 +1,12 @@
1
+ ## 1.1.0 - 2019-02-27
2
+
3
+ - dump the version of the compiler/interpreter in verbose mode
4
+ - fix gcc 4 (hello.c): add missing return value
5
+ - update obsolete dmd options
6
+
1
7
  ## 1.0.0 - 2019-02-21
2
8
 
3
- - gemify
9
+ - convert the script to a gem and release it
4
10
  - add tests for Deno, GraalVM JavaScript, Nim, and TruffleRuby
5
11
  - add --json option to render the results as a JSON array
6
12
  - add changelog
data/README.md CHANGED
@@ -7,17 +7,18 @@
7
7
  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
8
8
 
9
9
  - [NAME](#name)
10
- - [USAGE](#usage)
11
10
  - [INSTALLATION](#installation)
11
+ - [SYNOPSIS](#synopsis)
12
12
  - [DESCRIPTION](#description)
13
13
  - [Why?](#why)
14
- - [Example Output](#example-output)
14
+ - [OPTIONS](#options)
15
+ - [SAMPLE OUTPUT](#sample-output)
15
16
  - [PREREQUISITES](#prerequisites)
16
- - [Further Reading](#further-reading)
17
- - [See Also](#see-also)
18
- - [Author](#author)
19
- - [Version](#version)
20
- - [Copyright and License](#copyright-and-license)
17
+ - [REFERENCES](#references)
18
+ - [SEE ALSO](#see-also)
19
+ - [AUTHOR](#author)
20
+ - [VERSION](#version)
21
+ - [COPYRIGHT AND LICENSE](#copyright-and-license)
21
22
 
22
23
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
23
24
 
@@ -25,7 +26,13 @@
25
26
 
26
27
  startup-time - a command-line benchmarking tool which measures the startup times of programs in various languages
27
28
 
28
- ## USAGE
29
+ ## INSTALLATION
30
+
31
+ ```sh
32
+ $ gem install startup-time
33
+ ```
34
+
35
+ ## SYNOPSIS
29
36
 
30
37
  ```sh
31
38
  # run all available tests
@@ -44,48 +51,73 @@ $ startup-time --only jvm
44
51
  $ startup-time --only fast --omit slow-compile
45
52
 
46
53
  # increase the number of times each test is run (default: 10)
47
- $ startup-time --rounds 100
48
- ```
49
-
50
- ## INSTALLATION
51
-
52
- ```sh
53
- $ gem install startup-time
54
+ $ startup-time --count 100
54
55
  ```
55
56
 
56
57
  ## DESCRIPTION
57
58
 
58
- A command-line tool which measures how long it takes to execute ["Hello, world!"](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program) programs written in various languages. It records the fastest time for each program and prints a sorted table of the times after each run. Apart from the [prerequisites](#prerequisites) listed below, the tool doesn't require any of the tested languages to be installed: if a compiler/interpreter is not available, the test is skipped.
59
+ A command-line tool which measures how long it takes to execute ["Hello, world!"](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program)
60
+ programs written in various languages. It records the fastest time for each program and prints a sorted table of the times after each run.
61
+ Apart from the [prerequisites](#prerequisites) listed below, the tool doesn't require any of the tested languages to be installed: if a
62
+ compiler/interpreter is not available, the test is skipped.
59
63
 
60
64
  ### Why?
61
65
 
62
- To determine which languages are practical (or impractical) to use for command-line interface (CLI) programs. Anything under
63
- [100 milliseconds](https://www.nngroup.com/articles/response-times-3-important-limits/) is perceived as instantaneous. Anything over that is perceived as delayed, which can tangibly impair productivity and flow, and even risk breaking the user's train of thought.
66
+ To determine which languages are practical (or impractical) to use for command-line interface (CLI) tools. Anything under
67
+ [100 milliseconds](https://www.nngroup.com/articles/response-times-3-important-limits/) is perceived as instantaneous.
68
+ Anything over that is perceptibly delayed, which can impair interactivity and productivity on the command line, and can
69
+ mean the difference between staying in the zone and losing your train of thought.
70
+
71
+ ## OPTIONS
72
+
73
+ ```
74
+ USAGE:
75
+
76
+ startup-time [options]
77
+
78
+ OPTIONS:
79
+
80
+ -c, --count, --rounds INTEGER The number of times to execute each test (default: 10)
81
+ --clean Remove the build directory and exit
82
+ (targets will be recompiled on the next run)
83
+ -d, --dir PATH Specify the build directory
84
+ (default: ${XDG_CONFIG_HOME:-~/.cache/startup-time})
85
+ -h, --help Show this help message and exit
86
+ -H, --help-only, --help-omit Show the IDs and groups that can be passed to --only and --omit
87
+ -j, --json Output the results in JSON format (implies --quiet)
88
+ -o, --only LIST Only execute the specified tests (comma-separated list of IDs/groups)
89
+ -O, --omit LIST Don't execute the specified tests (comma-separated list of IDs/groups)
90
+ -q, --quiet Suppress all inessential output
91
+ -v, --verbose Enable verbose logging
92
+ -V, --version Display the version and exit
93
+ ```
64
94
 
65
- ### Example Output
95
+ ## SAMPLE OUTPUT
66
96
 
67
97
  Test Time (ms)
68
98
  C (gcc) 0.33
69
- Nim 0.45
70
- LuaJIT 0.62
71
- Rust 0.63
72
- Kotlin Native (konan) 0.66
73
- Go 0.75
74
- Lua 1.00
75
- Haskell (GHC) 1.17
99
+ Nim 0.44
100
+ Kotlin Native 0.61
101
+ LuaJIT 0.64
102
+ Go 0.66
103
+ Rust 0.67
104
+ D (DMD) 0.88
105
+ Lua 0.98
106
+ D (GDC) 1.10
107
+ Haskell (GHC) 1.14
76
108
  C++ (g++) 1.24
77
- Perl 1.75
109
+ Perl 1.69
78
110
  Java Native (GraalVM) 1.95
79
- Crystal 2.20
80
- Bash 3.37
81
- JavaScript (Deno) 11.18
82
- Python 3 26.41
83
- JavaScript (GraalVM) 35.58
84
- Java 56.40
85
- Python 2 57.00
86
- JavaScript (Node.js) 71.61
87
- Ruby 77.30
88
- Ruby (TruffleRuby) 91.28
111
+ Crystal 2.10
112
+ Bash 3.36
113
+ JavaScript (Deno) 11.15
114
+ Python 3 25.68
115
+ JavaScript (GraalVM) 32.38
116
+ Java 54.59
117
+ Python 2 56.30
118
+ JavaScript (Node.js) 70.39
119
+ Ruby 77.04
120
+ Ruby (TruffleRuby) 81.77
89
121
  Kotlin 103.02
90
122
  Scala 801.21
91
123
 
@@ -93,27 +125,26 @@ To determine which languages are practical (or impractical) to use for command-l
93
125
 
94
126
  - Ruby >= 2.4
95
127
 
96
- ## Further Reading
128
+ ## REFERENCES
97
129
 
98
130
  - [Response Times: The 3 Important Limits](https://www.nngroup.com/articles/response-times-3-important-limits/)
99
131
  - [100 milliseconds](http://cogsci.stackexchange.com/questions/1664/what-is-the-threshold-where-actions-are-perceived-as-instant)
100
- - [The Great Startup Problem](http://mail.openjdk.java.net/pipermail/mlvm-dev/2014-August/005866.html)
101
132
 
102
- ## See Also
133
+ ## SEE ALSO
103
134
 
104
135
  - [gnustavo/startup-times](https://github.com/gnustavo/startup-times) - a script to investigate the startup times of several programming languages
105
136
  - [jwiegley/helloworld](https://github.com/jwiegley/helloworld) - a comparison of "Hello, world" startup times in various languages
106
137
  - [sharkdp/hyperfine](https://github.com/sharkdp/hyperfine) - a command-line benchmarking tool
107
138
 
108
- ## Author
139
+ ## AUTHOR
109
140
 
110
141
  [chocolateboy](mailto:chocolate@cpan.org)
111
142
 
112
- ## Version
143
+ ## VERSION
113
144
 
114
- 1.0.0
145
+ 1.1.0
115
146
 
116
- ## Copyright and License
147
+ ## COPYRIGHT AND LICENSE
117
148
 
118
149
  Copyright © 2015-2019 by chocolateboy
119
150
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'benchmark'
4
+ require 'bundler/setup'
4
5
  require 'komenda'
5
6
  require 'shellwords' # for Array#shelljoin
6
7
  require 'tty/table'
@@ -11,8 +12,9 @@ module StartupTime
11
12
  class App
12
13
  EXPECTED_OUTPUT = /\AHello, world!\r?\n\z/
13
14
 
15
+ include FileUtils # for `sh`
14
16
  include Util # for `which`
15
- include Services.mixin %i[builder ids_to_groups options selected_tests]
17
+ include Services.mixin %i[builder ids_to_groups selected_tests]
16
18
 
17
19
  def initialize(args = ARGV)
18
20
  @options = Options.new(args)
@@ -65,7 +67,7 @@ module StartupTime
65
67
 
66
68
  sorted = @times.sort_by { |result| result[:time] }
67
69
 
68
- if options.format == :json
70
+ if @options.format == :json
69
71
  require 'json'
70
72
  puts sorted.to_json
71
73
  elsif !sorted.empty?
@@ -94,16 +96,47 @@ module StartupTime
94
96
  args = Array(test[:command])
95
97
 
96
98
  if args.size == 1 # native executable
99
+ compiler = test[:compiler] || id
97
100
  cmd = File.absolute_path(args.first)
98
- return unless File.exist? cmd
101
+ return unless File.exist?(cmd)
99
102
  else # interpreter + source
100
- cmd = which(args.first)
103
+ compiler = args.first
104
+ cmd = which(compiler)
101
105
  return unless cmd
102
106
  end
103
107
 
108
+ # dump the compiler/interpreter's version if running in verbose mode
109
+ if @verbosity == :verbose
110
+ puts
111
+ puts "test: #{id}"
112
+
113
+ # false (don't print the program's version); otherwise, a command
114
+ # (template string) to execute to dump the version
115
+ version = test[:version]
116
+
117
+ unless version == false
118
+ version ||= '%{compiler} --version'
119
+
120
+ # the compiler may have been uninstalled since the target was
121
+ # built, so make sure it still exists
122
+ if (compiler_path = which(compiler))
123
+ version_command = version % { compiler: compiler_path }
124
+ sh version_command
125
+ end
126
+ end
127
+ end
128
+
104
129
  argv0 = args.shift
105
130
  command = [cmd, *args]
106
131
 
132
+ unless @verbosity == :quiet
133
+ if @verbosity == :verbose
134
+ puts "command: #{command.shelljoin}"
135
+ else
136
+ print '.'
137
+ end
138
+ end
139
+
107
140
  # make sure the command produces the expected output
108
141
  result = Komenda.run(command)
109
142
  output = result.output
@@ -118,17 +151,13 @@ module StartupTime
118
151
 
119
152
  times = []
120
153
 
121
- unless @verbosity == :quiet
122
- if @verbosity == :verbose
123
- puts "#{id}: #{command.shelljoin}"
124
- else
125
- print '.'
126
- end
127
- end
128
-
129
- @options.rounds.times do
130
- times << Benchmark.realtime do
131
- system([cmd, argv0], *args, out: File::NULL)
154
+ # the bundler environment slows down ruby and breaks truffle-ruby,
155
+ # so make sure it's disabled for the benchmark
156
+ Bundler.with_clean_env do
157
+ @options.rounds.times do
158
+ times << Benchmark.realtime do
159
+ system([cmd, argv0], *args, out: File::NULL)
160
+ end
132
161
  end
133
162
  end
134
163
 
@@ -48,8 +48,8 @@ module StartupTime
48
48
 
49
49
  opts.on(
50
50
  '--clean',
51
- 'Remove the build directory and exit (targets will be ',
52
- 'recompiled on the next run)'
51
+ 'Remove the build directory and exit',
52
+ '(targets will be recompiled on the next run)'
53
53
  ) do
54
54
  @action = :clean
55
55
  end
@@ -58,7 +58,8 @@ module StartupTime
58
58
  '-d',
59
59
  '--dir PATH',
60
60
  String,
61
- "Specify the build directory (default: #{BUILD_DIR})"
61
+ 'Specify the build directory',
62
+ "(default: #{BUILD_DIR})"
62
63
  ) do |value|
63
64
  @build_dir = value
64
65
  end
@@ -93,8 +94,7 @@ module StartupTime
93
94
  '-o',
94
95
  '--only LIST',
95
96
  Array, # comma-separated strings
96
- 'Only execute the specified tests (comma-separated list of ',
97
- 'IDs/groups)'
97
+ 'Only execute the specified tests (comma-separated list of IDs/groups)'
98
98
  ) do |values|
99
99
  values.each { |value| registry.only(value.strip) }
100
100
  end
@@ -103,8 +103,7 @@ module StartupTime
103
103
  '-O',
104
104
  '--omit LIST',
105
105
  Array, # comma-separated strings
106
- "Don't execute the specified tests (comma-separated list ",
107
- 'of IDs/groups)'
106
+ "Don't execute the specified tests (comma-separated list of IDs/groups)"
108
107
  ) do |values|
109
108
  values.each { |value| registry.omit(value.strip) }
110
109
  end
@@ -46,7 +46,7 @@ module StartupTime
46
46
  @only = Set.new
47
47
  end
48
48
 
49
- # remove the specified test(s) from the set of enabled tests
49
+ # add the specified test(s) to the set of disabled tests
50
50
  def omit(id)
51
51
  @omit.merge(ids_for(id))
52
52
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StartupTime
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
@@ -2,4 +2,5 @@
2
2
 
3
3
  int main(int argc, char * argv[]) {
4
4
  printf("Hello, world!\n");
5
+ return 0;
5
6
  }
@@ -1,12 +1,13 @@
1
1
  ---
2
- # anything < 10ms on my system is arbitrarily tagged :fast
3
- # anything > 50ms on my system is arbitrarily tagged :slow
2
+ # anything < 10 ms on my system is arbitrarily tagged :fast
3
+ # anything > ~100 ms on my system is tagged :slow
4
4
 
5
5
  bash:
6
6
  name: Bash
7
7
  groups:
8
8
  - fast
9
9
  - script
10
+ version: '%{compiler} --version | head -n1'
10
11
  command:
11
12
  - bash
12
13
  - hello.bash
@@ -17,6 +18,7 @@ crystal:
17
18
  - compiled
18
19
  - fast
19
20
  - native
21
+ - slow-compile
20
22
  source: hello.cr
21
23
  compile: '%{compiler} build --release -o %{target} %{source}'
22
24
  command: hello.cr.out
@@ -40,7 +42,8 @@ dmd:
40
42
  - fast
41
43
  - native
42
44
  source: hello.d
43
- compile: '%{compiler} -O3 -o %{target} %{source}'
45
+ compile: '%{compiler} -O -of=%{target} %{source}'
46
+ version: '%{compiler} --version | head -n1'
44
47
  command: hello.dmd.d.out
45
48
 
46
49
  g++:
@@ -53,6 +56,7 @@ g++:
53
56
  - native
54
57
  source: hello.cpp
55
58
  compile: '%{compiler} -O3 -o %{target} %{source}'
59
+ version: '%{compiler} --version | head -n1'
56
60
  command: hello.gpp.out
57
61
 
58
62
  gcc:
@@ -62,9 +66,9 @@ gcc:
62
66
  - compiled
63
67
  - fast
64
68
  - native
65
- - no-ci # XXX flaky on Travis
66
69
  source: hello.c
67
70
  compile: '%{compiler} -O3 -o %{target} %{source}'
71
+ version: '%{compiler} --version | head -n1'
68
72
  command: hello.gcc.out
69
73
 
70
74
  gdc:
@@ -76,6 +80,7 @@ gdc:
76
80
  - native
77
81
  source: hello.d
78
82
  compile: '%{compiler} -O3 -o %{target} %{source}'
83
+ version: '%{compiler} --version | head -n1'
79
84
  command: hello.gdc.d.out
80
85
 
81
86
  ghc:
@@ -97,6 +102,7 @@ go:
97
102
  - native
98
103
  source: hello.go
99
104
  compile: '%{compiler} build -o %{target} %{source}'
105
+ version: '%{compiler} version'
100
106
  command: hello.go.out
101
107
 
102
108
  graalvm-js:
@@ -104,6 +110,7 @@ graalvm-js:
104
110
  groups:
105
111
  - js
106
112
  - script
113
+ version: '%{compiler} --version'
107
114
  command:
108
115
  - js
109
116
  - hello.js
@@ -115,6 +122,7 @@ javac:
115
122
  - java
116
123
  - jvm
117
124
  source: HelloJava.java
125
+ version: '%{compiler} -version'
118
126
  command:
119
127
  - java
120
128
  - HelloJava
@@ -140,6 +148,8 @@ kotlinc-native:
140
148
  - native
141
149
  - slow-compile
142
150
  source: HelloKotlin.kt
151
+ compiler: konanc
152
+ version: '%{compiler} -version'
143
153
  command: hello.kt.out
144
154
 
145
155
  kotlinc:
@@ -152,6 +162,7 @@ kotlinc:
152
162
  source: HelloKotlin.kt
153
163
  target: HelloKotlinKt.class
154
164
  compile: '%{compiler} %{source}'
165
+ version: '%{compiler} -version'
155
166
  command:
156
167
  - kotlin
157
168
  - HelloKotlinKt
@@ -173,6 +184,7 @@ lua:
173
184
  - fast
174
185
  - luas
175
186
  - script
187
+ version: '%{compiler} -v'
176
188
  command:
177
189
  - lua
178
190
  - hello.lua
@@ -183,6 +195,7 @@ luajit:
183
195
  - fast
184
196
  - luas
185
197
  - script
198
+ version: '%{compiler} -v'
186
199
  command:
187
200
  - luajit
188
201
  - hello.lua
@@ -195,6 +208,7 @@ nim:
195
208
  - native
196
209
  source: hello.nim
197
210
  compile: '%{compiler} compile --out:%{target} --opt:speed --verbosity:0 --hints:off %{source}'
211
+ version: '%{compiler} --version | head -n1'
198
212
  command: hello.nim.out
199
213
 
200
214
  node:
@@ -212,6 +226,8 @@ perl5:
212
226
  - fast
213
227
  - perl
214
228
  - script
229
+ # trim perl's lengthy version output
230
+ version: "%{compiler} -MConfig -le 'print qq($^V $Config{archname})'"
215
231
  command:
216
232
  - perl
217
233
  - hello.pl
@@ -271,6 +287,7 @@ scalac:
271
287
  - slowest
272
288
  source: HelloScala.scala
273
289
  compile: '%{compiler} %{source}'
290
+ version: '%{compiler} -version'
274
291
  command:
275
292
  - scala
276
293
  - HelloScala
@@ -278,9 +295,9 @@ scalac:
278
295
  truffle-ruby:
279
296
  name: Ruby (TruffleRuby)
280
297
  groups:
281
- - no-test # doesn't work inside bundler
282
298
  - rubies
283
299
  - script
300
+ version: '%{compiler} --version'
284
301
  command:
285
302
  - truffleruby
286
303
  - hello.rb
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: startup-time
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - chocolateboy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-21 00:00:00.000000000 Z
11
+ date: 2019-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: cli-pasta
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -122,20 +136,6 @@ dependencies:
122
136
  - - "~>"
123
137
  - !ruby/object:Gem::Version
124
138
  version: 0.0.2
125
- - !ruby/object:Gem::Dependency
126
- name: bundler
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '2.0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '2.0'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: rubocop
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -150,7 +150,7 @@ dependencies:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
152
  version: 0.65.0
153
- description: A benchmarking tool which tests how long it takes to execute "Hello,
153
+ description: A benchmarking tool which measures how long it takes to execute "Hello,
154
154
  world!" programs in various languages.
155
155
  email: chocolate@cpan.org
156
156
  executables: