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 +4 -4
- data/README.md +22 -0
- data/lib/fast_stack.rb +42 -2
- data/spec/fast_stack_spec.rb +0 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7b203e805558207a896a66af413dfbbf48fbf0d
|
4
|
+
data.tar.gz: f8aaa3a556df3007d936e21c7983512ab04f1eea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
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
|
data/spec/fast_stack_spec.rb
CHANGED