Giter VIP home page Giter VIP logo

Comments (8)

HertzDevil avatar HertzDevil commented on July 21, 2024

Is this exclusive to Crystal? Do other languages exhibit a similar speed difference?

from crystal.

devnote-dev avatar devnote-dev commented on July 21, 2024

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.

straight-shoota avatar straight-shoota commented on July 21, 2024

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.

straight-shoota avatar straight-shoota commented on July 21, 2024

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.

devnote-dev avatar devnote-dev commented on July 21, 2024

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.

ysbaddaden avatar ysbaddaden commented on July 21, 2024

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.

devnote-dev avatar devnote-dev commented on July 21, 2024

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.

ysbaddaden avatar ysbaddaden commented on July 21, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.