Comments (8)
Is this exclusive to Crystal? Do other languages exhibit a similar speed difference?
from crystal.
I believe so, although I wasn't entirely sure how to test this (using go 1.19):
package main
import (
"fmt"
"runtime/debug"
)
func fail() {
panic("uh oh!")
}
func main() {
defer func() {
if err := recover(); err != nil {
fmt.Printf("%s\n", err)
fmt.Printf("%+v\n", string(debug.Stack()))
}
}()
fail()
}
$ go build test.go
$ time ./test
uh oh!
goroutine 1 [running]:
runtime/debug.Stack()
/usr/local/go/src/runtime/debug/stack.go:24 +0x65
main.main.func1()
/mnt/c/Users/user/Documents/arachnid/test.go:16 +0x70
panic({0x48a3e0, 0x4b84e0})
/usr/local/go/src/runtime/panic.go:884 +0x213
main.fail(...)
/mnt/c/Users/user/Documents/arachnid/test.go:9
main.main()
/mnt/c/Users/user/Documents/arachnid/test.go:20 +0x4a
./test 0.00s user 0.02s system 8% cpu 0.254 total
C:\> go build test.go
C:\> Measure-Command { .\test.exe }
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 89
Ticks : 898827
TotalDays : 1.04030902777778E-06
TotalHours : 2.49674166666667E-05
TotalMinutes : 0.001498045
TotalSeconds : 0.0898827
TotalMilliseconds : 89.8827
from crystal.
I tried exactly the same, also on WSL2 with Ubuntu and I see a very different performance.
$ time ./caller
[".test/caller.cr:1:6 in '__crystal_main'", "/home/linuxbrew/.linuxbrew/Cellar/crystal/1.11.2/share/crystal/src/crystal/main.cr:129:5 in 'main_user_code'", "/home/linuxbrew/.lin
uxbrew/Cellar/crystal/1.11.2/share/crystal/src/crystal/main.cr:115:7 in 'main'", "/home/linuxbrew/.linuxbrew/Cellar/crystal/1.11.2/share/crystal/src/crystal/main.cr:141:3 in 'ma
in'", "/lib/x86_64-linux-gnu/libc.so.6 in '??'", "/lib/x86_64-linux-gnu/libc.so.6 in '__libc_start_main'", "./caller in '_start'", "???"]
./caller 0,01s user 0,02s system 97% cpu 0,030 total
$ Measure-Command { .\caller.exe }
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 150
Ticks : 1509557
TotalDays : 1,7471724537037E-06
TotalHours : 4,19321388888889E-05
TotalMinutes : 0,00251592833333333
TotalSeconds : 0,1509557
TotalMilliseconds : 150,9557
from crystal.
Measuring the entire execution time of the program is not precise enough to make a reasonable asessment of unwinding performance. There's a lot of other runtime differences between the platforms.
Could you try this program on your machine? It should more accurately show the time it takes to build the call stack.
c = nil
time = Time.measure { c = caller }
puts c
puts time
For me it shows around 0.027 on Linux and 0.044 on Windows.
from crystal.
WSL:
["test.cr:2:23 in '__crystal_main'", "/home/devonte/.local/share/crimson/crystal/1.11.2/share/crystal/src/crystal/main.cr:129:5 in 'main_user_code'", "/home/devonte/.local/share/crimson/crystal/1.11.2/share/crystal/src/crystal/main.cr:115:7 in 'main'", "/home/devonte/.local/share/crimson/crystal/1.11.2/share/crystal/src/crystal/main.cr:141:3 in 'main'", "/lib/x86_64-linux-gnu/libc.so.6 in '??'", "/lib/x86_64-linux-gnu/libc.so.6 in '__libc_start_main'", "./test in '_start'", "???"]
00:00:08.466442158
Windows:
["test.cr:2 in '__crystal_main'", "C:\\Users\\user\\AppData\\Local\\Programs\\Crystal-Installer\\src\\crystal\\main.cr:129 in 'main_user_code'", "C:\\Users\\user\\AppData\\Local\\Programs\\Crystal-Installer\\src\\crystal\\main.cr:115 in 'main'", "C:\\Users\\user\\AppData\\Local\\Programs\\Crystal-Installer\\src\\crystal\\main.cr:141 in 'main'", "C:\\Users\\user\\AppData\\Local\\Programs\\Crystal-Installer\\src\\crystal\\system\\win32\\wmain.cr:37 in 'wmain'", "d:\\a01\\_work\\12\\s\\src\\vctools\\crt\\vcstartup\\src\\startup\\exe_common.inl:288 in '__scrt_common_main_seh'", "C:\\WINDOWS\\System32\\KERNEL32.DLL +75133 in 'BaseThreadInitThunk'", "C:\\WINDOWS\\SYSTEM32\\ntdll.dll +371288 in 'RtlUserThreadStart'"]
00:00:00.172470300
from crystal.
It could be interesting to see what happens with --no-debug
or calling caller
twice and measure the second call only, to see which of unwinding the symbols or decoding the debug tables from the executable takes time.
from crystal.
WSL no debug:
["./test in 'Exception::CallStack::unwind:Array(Pointer(Void))'", "./test in 'Exception::CallStack#initialize:Array(Pointer(Void))'", "./test in 'Exception::CallStack::new:Exception::CallStack'", "./test in 'caller:Array(String)'", "./test in '__crystal_main'", "./test in 'Crystal::main_user_code<Int32, Pointer(Pointer(UInt8))>:Nil'", "./test in 'Crystal::main<Int32, Pointer(Pointer(UInt8))>:Int32'", "./test in 'main'", "/lib/x86_64-linux-gnu/libc.so.6 in '??'", "/lib/x86_64-linux-gnu/libc.so.6 in '__libc_start_main'", "./test in '_start'", "???"]
00:00:00.119909135
Windows no debug:
["test.exe +81046 in '??'", "test.exe +80942 in '??'", "test.exe +80906 in '??'", "test.exe +70889 in '??'", "test.exe +5464 in '??'", "test.exe +727929 in '??'", "test.exe +727706 in '??'", "test.exe +66073 in '??'", "test.exe +66355 in '??'", "test.exe +786700 in '??'", "C:\\WINDOWS\\System32\\KERNEL32.DLL +75133 in 'BaseThreadInitThunk'", "C:\\WINDOWS\\SYSTEM32\\ntdll.dll +371288 in 'RtlUserThreadStart'"]
00:00:00.099170400
WSL 2nd caller:
["test.cr:3:23 in '__crystal_main'", "/home/devonte/.local/share/crimson/crystal/1.11.2/share/crystal/src/crystal/main.cr:129:5 in 'main_user_code'", "/home/devonte/.local/share/crimson/crystal/1.11.2/share/crystal/src/crystal/main.cr:115:7 in 'main'", "/home/devonte/.local/share/crimson/crystal/1.11.2/share/crystal/src/crystal/main.cr:141:3 in 'main'", "/lib/x86_64-linux-gnu/libc.so.6 in '??'", "/lib/x86_64-linux-gnu/libc.so.6 in '__libc_start_main'", "./test in '_start'", "???"]
00:00:00.001196319
Windows 2nd caller:
["test.cr:3 in '__crystal_main'", "C:\\Users\\user\\AppData\\Local\\Programs\\Crystal-Installer\\src\\crystal\\main.cr:129 in 'main_user_code'", "C:\\Users\\user\\AppData\\Local\\Programs\\Crystal-Installer\\src\\crystal\\main.cr:115 in 'main'", "C:\\Users\\user\\AppData\\Local\\Programs\\Crystal-Installer\\src\\crystal\\main.cr:141 in 'main'", "C:\\Users\\user\\AppData\\Local\\Programs\\Crystal-Installer\\src\\crystal\\system\\win32\\wmain.cr:37 in 'wmain'", "d:\\a01\\_work\\12\\s\\src\\vctools\\crt\\vcstartup\\src\\startup\\exe_common.inl:288 in '__scrt_common_main_seh'", "C:\\WINDOWS\\System32\\KERNEL32.DLL +75133 in 'BaseThreadInitThunk'", "C:\\WINDOWS\\SYSTEM32\\ntdll.dll +371288 in 'RtlUserThreadStart'"]
00:00:00.001635100
WSL no debug & 2nd caller:
["./test in 'Exception::CallStack::unwind:Array(Pointer(Void))'", "./test in 'Exception::CallStack#initialize:Array(Pointer(Void))'", "./test in 'Exception::CallStack::new:Exception::CallStack'", "./test in 'caller:Array(String)'", "./test in '__crystal_main'", "./test in 'Crystal::main_user_code<Int32, Pointer(Pointer(UInt8))>:Nil'", "./test in 'Crystal::main<Int32, Pointer(Pointer(UInt8))>:Int32'", "./test in 'main'", "/lib/x86_64-linux-gnu/libc.so.6 in '??'", "/lib/x86_64-linux-gnu/libc.so.6 in '__libc_start_main'", "./test in '_start'", "???"]
00:00:00.001927353
Windows no debug & 2nd caller:
["test.exe +81046 in '??'", "test.exe +80942 in '??'", "test.exe +80906 in '??'", "test.exe +70889 in '??'", "test.exe +5469 in '??'", "test.exe +727929 in '??'", "test.exe +727706 in '??'", "test.exe +66073 in '??'", "test.exe +66355 in '??'", "test.exe +786700 in '??'", "C:\\WINDOWS\\System32\\KERNEL32.DLL +75133 in 'BaseThreadInitThunk'", "C:\\WINDOWS\\SYSTEM32\\ntdll.dll +371288 in 'RtlUserThreadStart'"]
00:00:00.001013300
from crystal.
Thanks! So unwinding ain't the problem, same for mapping symbols to a file:line. The problem seems to be the parsing of the executable debug lines section?
from crystal.
Related Issues (20)
- Can't initialize a struct inside `#pre_initialize` HOT 4
- Unable to run interpreter after building HOT 2
- Using `lld-link` as a linker HOT 1
- Interpreter bug when `require "http/server"` HOT 1
- Can't instantiate a UNIXSocket instance in the interpreter HOT 2
- Some `#[]?(Range)` methods can still raise `IndexError`
- Interpreter hits Invalid memory access (after Error: BUG: no target defs) HOT 1
- Multiplication of Int64 and Int32 may result in Int32 (risking overflows at runtime) HOT 4
- Huge `JSON::ParseException` HOT 5
- `Number#humanize` and `Int#humanize_bytes` should separate number and unit by a space HOT 1
- Regression: Interrupted system call in CI HOT 6
- Is an html strip-tags method a worth stdlib addition? HOT 7
- add something like ruby un.rb or cmake -E for cross platform scripts HOT 3
- regression: XPath swallows errors and raises opaque `error in [...] expression` instead HOT 1
- Proposal: Utility method for string truncation HOT 2
- Debugging Windows binaries with LLDB doesn't break on access violation
- Manage compiler dependencies with `shards` HOT 6
- Passing `Proc`s with non-default calling conventions across libs HOT 4
- Standardizing the type for timeout values HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from crystal.