<FromGitter>
<Daniel-Worrall> The problem is that crystal is not ruby
<FromGitter>
<Blacksmoke16> indeed
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
f1refly has quit [Ping timeout: 246 seconds]
f1reflyylmao has joined #crystal-lang
<FromGitter>
<wyhaines> @pciuch9, Crystal has a lot of the same ergonomics of Ruby, and it generally looks and feels like Ruby, but it isn't Ruby. ⏎ ⏎ When porting Ruby code, sometimes you need to make changes. ⏎ ⏎ IMHO, writing ... [https://gitter.im/crystal-lang/crystal?at=5f77e060b7db72780a1d1f70]
<FromGitter>
<HertzDevil> someone said >3 years ago that everything is covariant when considering method overloads, and it seems the situation hasn't changed ever since
<FromGitter>
<Blacksmoke16> compiler wouldnt include anything the code you actually use doesn't so its not *terrible*
<FromGitter>
<j8r> I would like to make my web router to have a special route, which serves the application's API docs
<FromGitter>
<Blacksmoke16> wouldn't that just be a matter of displaying the swagger page?
<FromGitter>
<Blacksmoke16> or really does a redirect to `./docs` :p
<FromGitter>
<j8r> Swagger docs is more for the users, here it will be Crystal API docs of the classes/methods etc
<FromGitter>
<j8r> Not really, because ideally not having to install crystal will be better
<FromGitter>
<j8r> I could use a hack like `{{ `crystal docs` }}`, and embed the docs somehow in the app
<FromGitter>
<Blacksmoke16> hm yea
<FromGitter>
<Blacksmoke16> any reason the user should be generating them in the first place? They're static so can just host it on GH pages no?
<oprypin>
j8r, you definitely shouldnt generate docs on the fly
<FromGitter>
<j8r> That's simpler. One can have `/swagger` and `/api` out of the box
<FromGitter>
<Blacksmoke16> have a `postinstall: crystal docs`
<FromGitter>
<j8r> of `/api-docs` - you get the idea
<FromGitter>
<Blacksmoke16> but imo id kinda not want that route auto added, like you would need a way to disable it in prod etc
<FromGitter>
<j8r> Not automatically sure
<FromGitter>
<j8r> Can be behind a flag, or anything
<FromGitter>
<j8r> or environment variable, like for swagger docs - not everyone does Open Source ;)
<FromGitter>
<Blacksmoke16> fair enough
<FromGitter>
<j8r> If docs are generated separately, we have to make an archive to bundle the docs with the app somehow, and put them in a proper location server by the http server/application
<FromGitter>
<Blacksmoke16> im still not sold on the need to include your framework docs with a user's application
<FromGitter>
<j8r> that's done with Swagger docs, quite frequent to do so
<FromGitter>
<Blacksmoke16> yea but swagger docs would be describing their application's endpoint, anyone who isnt devving on the app itself doesnt need to know about the framework
<FromGitter>
<j8r> it will be Crystal API docs of the app, not the framework itself.
<FromGitter>
<Blacksmoke16> ahh ok, that was the missing piece of info
<FromGitter>
<Blacksmoke16> id just let them worry about it if they want
<FromGitter>
<j8r> probably
<oprypin>
what a weird thing to write. `File.open(file, &.read_line)`
<oprypin>
wait, how do i make a temporary directory?
<FromGitter>
<j8r> Use `Dir.mkdir File.tempname`
<FromGitter>
<j8r> not a fan though
deavmi has quit [Quit: Eish! Load shedding.]
deavmi has joined #crystal-lang
<FromGitter>
<mattrberry> @oprypin I just recorded it with the default perf settings that hotspot uses. I also didn’t build with —debug. I’ll give that a shot and see if it look’s any different when I get out of bed
<oprypin>
well yea that's exactly what puts debug info
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
_whitelogger has joined #crystal-lang
<FromGitter>
<mattrberry> @oprypin Doesn't `crystal build` build for debug by default? I know it sets the `debug` compile-time flag..
<FromGitter>
<mattrberry> Either way, the perf data is identical to what I sent earlier
<oprypin>
mattrberry, i dont think so,no
<oprypin>
--debug is definitely not just "lack of --release"
<FromGitter>
<mattrberry> Then why does it set the `debug` flag?
<oprypin>
dont know lol, maybe the debug flag *is* just lack of --release
<oprypin>
mattrberry, tbh maybe you need to build libgc with --debug
<oprypin>
or if youre on debianmaybe theres a dbg package for it
<oprypin>
"build libgc with --debug" is a misnomer, of course --debug flag is specific to crystal and that one probably has some different way to specify that it's debug mode :)
<oprypin>
@mattrberry: `ldd the_binary` will show the path to libgc and I'm just asking what provides that library - probably your distro, then what distro is it?
<FromGitter>
<mattrberry> I remember when I was working on my gameboy emulator and accidentally used classes instead of structs in one place, this is what it looked like because the gc was busy clearing everything
<FromGitter>
<mattrberry> But this program should only have like 5 objects instantiated that remain over the lifetime of the program..
<FromGitter>
<mattrberry> Everything else should be a value
<FromGitter>
<mattrberry> I'm totally lost on how to continue debugging this lol
<FromGitter>
<mattrberry> But if I can't figure that out, gba on crystal is gonna be a pita
<FromGitter>
<asterite> what's the problem?
<FromGitter>
<asterite> I usually use instruments on Mac, it tells you which method takes the most time
<FromGitter>
<asterite> it looks like include? takes most of the time?
<FromGitter>
<asterite> also, if you can share a snippet or benchmark, I can run it on my machine and see if I can figure it out
<FromGitter>
<asterite> it's strange that you can't see the class names... using instruments on Mac I see the full name of the function, which includes the class name
<oprypin>
asterite, it's likely not a "snippet" but a whole complicated program (emulator). possibly even running a ROM
<FromGitter>
<asterite> Ah, I see. I can try that too
<FromGitter>
<mattrberry> @asterite Yeah I have a lot of optimization to do in the emulator itself still. I can get the includes? down to basically 0 with a little uglier code. My main concern at the moment is the 35% spent outside of the main program code. Any idea what might be contributing to that? I assumed it might be gc, but it's still there when compiling with `-Dgc_none`
<FromGitter>
<mattrberry> Plus I don't believe I'm ever creating objects that need to be gc'd
<oprypin>
mattrberry, so can you send someone everything needed to run this?
<FromGitter>
<mattrberry> Yeah here's the repo right now. It's still pretty basic. If you don't have libsdl2 installed, I can tell you which lines to comment out. It should still have the same issue. I haven't created a minimal example yet though https://github.com/mattrberry/crab
<oprypin>
mattrberry, how to run it
<oprypin>
does it need input files or just run
<FromGitter>
<mattrberry> Without libsdl2, you'll need to comment out: ⏎ ⏎ ```src/crab.cr:2 ⏎ src/crab/gba.cr:21 ⏎ src/crab/gba.cr:22 ⏎ src/crab/gba.cr:23``` ⏎ ⏎ and the contents of both methods in Display.cr [https://gitter.im/crystal-lang/crystal?at=5f78f282dfe47e4d5746c0be]
<FromGitter>
<mattrberry> Oh yeah, let me send you a rom
<FromGitter>
<mattrberry> Oh interesting, I must have had it installed before I added the version line. My b
<FromGitter>
<mattrberry> Hmm as a side note, the shards install works fine for me even after deleting lib/. I wonder why that's not resolving for you guys..
<FromGitter>
<mattrberry> Hmm, according to this, much of the stuff grouped under the ?? is my methods as well. I wonder why it's grouping it outside of the main_user_code there?
<FromGitter>
<mattrberry> I guess I could just work on the easy optimizations that I'm already aware of and see if that brings this other chunk back down..
<FromGitter>
<asterite> good catch, I don't know why it appears multiple times
<oprypin>
mattrberry, do u use threads??
<FromGitter>
<mattrberry> I don't use threads
<FromGitter>
<mattrberry> Unless you count the ones that SDL uses internally, but there aren't any outside of those
<FromGitter>
<asterite> Well, I suggested using instruments but I can't figure out what's slow from that... sorry
<FromGitter>
<mattrberry> Hey no worries! I appreciate both of you taking a look. I have to run, but I'll be back in a few hours to work on some other optimizations to see if that helps this issue..
<FromGitter>
<asterite> I found something
<FromGitter>
<asterite> In Bus#[] there's a to_u8
<FromGitter>
<asterite> the reason is that some of the `when` return an Int32 (the last two)
<FromGitter>
<asterite> If you change those 0xFF to 0xFF_u8 then you don't need that `to_u8` at the end
<FromGitter>
<asterite> I guess that method is called a lot, and the current way is creating a union, then doing a dispatch... when it's not necessary
<FromGitter>
<asterite> When I changed that the profile graph changes quite a bit
<FromGitter>
<asterite> Can you try it?
<FromGitter>
<asterite> In general, avoiding numeric unions whenever possible is best
<FromGitter>
<mattrberry> Oh wow, good to know. I do that in a couple of places in CryBoy
<FromGitter>
<mattrberry> I made the change on my end. Didn't seem to make a huge change in my perf graph, but it still bought me ~3 fps. I went from getting ~37-39 on this demo to now getting ~40-42
<FromGitter>
<mattrberry> Looks even more fun in release :p
<FromGitter>
<mattrberry> I have to run now unfortunately :/ I'll be back on in a few hours if you're still here :) Thanks again!!
<FromGitter>
<asterite> I'll be able to take a look at it again on Monday
<FromGitter>
<asterite> oh, crystal once is accessing a constant
<FromGitter>
<asterite> so probably those ??? come from that
<FromGitter>
<asterite> my bet is that inlining those range constants will improve things
<FromGitter>
<asterite> that said, there's no reason why those ranges need to use that crystal_once... but constants like that are not well optimized
<FromGitter>
<asterite> I wish we could optimize such constants... but I don't know how to detect these cases... maybe some other core team members, like waj and brian, can think of a solution
<FromGitter>
<asterite> When I inlined the constants, I see that Range#includes? is the bottleneck
<FromGitter>
<asterite> Also, where can I see the FPS?
<FromGitter>
<asterite> I think doing `n <= index <= y` instead of using a constant range is your best bet... until the compiler gets smarter. Range is a nice convenience but right now not very good in hot paths
<FromGitter>
<asterite> However, I just benchmarks doing `n <= index <= y` vs. `case index; n..y` and I'm seeing the same performance, so maybe using range is okay
<FromGitter>
<asterite> Then there's an optimization we can do in the stdlib: array and deque#clear will clear out the memory so the GC can collect references... but that's not needed if the array or deque just holds numbers