fast_stack 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5d6bf89b44f458eee3423d52a00738e01775dbb
4
- data.tar.gz: e5a1f5edd19dd540976f792f8a12f4c03cc6ed7e
3
+ metadata.gz: a7b203e805558207a896a66af413dfbbf48fbf0d
4
+ data.tar.gz: f8aaa3a556df3007d936e21c7983512ab04f1eea
5
5
  SHA512:
6
- metadata.gz: ceab9df8d2414a03f97ae9b7fd08f4c4970a52f32782603b391aa22cbd2c1347610dbd3e0c3b46f5a3ed5e213541e573ba2fffdf8b8232e89a6e944074deaa46
7
- data.tar.gz: f42ea3067770e197cfe00adcff3f0c7ec96507021db7f9690d24b4ebd741e2a70d2b8e5864b610abb256bc53d72be75fdef6968b15649664448318f815999c60
6
+ metadata.gz: 6eef1b4399175be510fc9a93c5948d0791b6d2139b3da100cbecd39fabe1fb3d33397d198faf91d2218fe6e20570e843dd71de9478f5fd2430cc8b6da21c7b02
7
+ data.tar.gz: fd2f07f355adb448f7feeeb716a5c9f748d9fccfe1baf9ad26bebea1bf9ff0894ea7eaddd61bd37a18f9d66aa19ed324e6308061d47ebcf9841bb7d21788cc09
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  ### Fast stack
2
2
 
3
+ Very efficient collection of ruby backtraces, even under heavy CPU load
3
4
 
4
5
  ### How do you use it?
5
6
 
@@ -8,4 +9,25 @@
8
9
  ### Usage
9
10
 
10
11
 
12
+ ```
13
+ def fib( n )
14
+ return n if ( 0..1 ).include? n
15
+ ( fib( n - 1 ) + fib( n - 2 ) )
16
+ end
17
+
18
+ stacks = FastStack.profile do
19
+ fib(30)
20
+ end
21
+
22
+ puts stacks.count
23
+ # 30
24
+
25
+ ```
26
+
27
+ ### Notes
28
+
29
+ This technique was conceived by https://github.com/tmm1 , big thank you.
30
+
31
+ Ruby 2.0 uses #backtrace_locations, 1.9.3 uses #backtrace
32
+
11
33
  (gem template based on https://github.com/CodeMonkeySteve/fast_xor )
data/lib/fast_stack.rb CHANGED
@@ -1,14 +1,54 @@
1
1
  require 'fast_stack/fast_stack'
2
2
  module FastStack
3
3
  def self.profile(millisecs=1, &blk)
4
+ done = false
4
5
  stacks = []
5
6
  thread = Thread.current
7
+ delta = millisecs / 1000.0
8
+ last_time = Time.new
9
+
10
+ new_api = thread.respond_to?(:backtrace_locations)
11
+
12
+ # NOTE not extracting to another method to avoid adding a frame
13
+ # to the stack
14
+
15
+ # this thread catches stuff fast stack does not
16
+ # the main case is catching sleeping threads
17
+ profile_thread = Thread.new do
18
+ until done
19
+ start = Time.new
20
+ if last_time < start - delta
21
+ last_time = start
22
+ stacks << (new_api ? thread.backtrace_locations : thread.backtrace)
23
+ end
24
+
25
+ sleep(delta)
26
+ end
27
+ end
6
28
 
7
29
  trap('PROF') do
8
- stacks << thread.backtrace_locations
30
+ start = Time.new
31
+ if last_time < start - delta
32
+ last_time = start
33
+ stack = (new_api ? thread.backtrace_locations : thread.backtrace)
34
+ # I am not sure if this is ensured to run in the thread
35
+ # though in my samples it does
36
+ if thread == Thread.current
37
+ stack = stack[2..-1]
38
+ # since we are in the same thread, might as well remove
39
+ # our overhead
40
+ start = Time.new
41
+ end
42
+ stacks << stack
43
+ end
9
44
  end
10
45
 
11
- profile_block(millisecs * 1000, &blk)
46
+ begin
47
+ profile_block(millisecs * 1000, &blk)
48
+ ensure
49
+ done = true
50
+ profile_thread.join
51
+ end
12
52
 
13
53
  stacks
14
54
  end
@@ -23,8 +23,6 @@ describe String do
23
23
  fib(30)
24
24
  end
25
25
 
26
- p s.count
27
-
28
26
  expect(s.count).to be > 10
29
27
  end
30
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fast_stack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron