ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.23.1 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
DTZUZO has quit [Quit: WeeChat 1.9]
faustinoaq has quit [Ping timeout: 240 seconds]
aroaminggeek is now known as aroaminggeek[awa
faustinoaq has joined #crystal-lang
derek-away is now known as daemonwrangler
daemonwrangler is now known as derek-away
saadq has quit [Ping timeout: 248 seconds]
<crystal-gh> [crystal] MakeNowJust opened pull request #5354: Fix the scope to look-up the constant as the receiver type of the macro (master...fix/crystal/lookup-scope-in-macro) https://git.io/vbnsz
DTZUZO has joined #crystal-lang
<crystal-gh> [crystal] faustinoaq opened pull request #5355: Avoid empty author and email (master...patch-1) https://git.io/vbnGX
<FromGitter> <Lispre> I love crystal
<FromGitter> <cyclecraze_twitter> Can anyone provide a status update on 1.0?
aroaminggeek[awa is now known as aroaminggeek
aroaminggeek is now known as aroaminggeek[awa
DTZUZO has quit [Ping timeout: 260 seconds]
aroaminggeek[awa is now known as aroaminggeek
illyohs has quit [Ping timeout: 240 seconds]
DTZUZO has joined #crystal-lang
snsei has joined #crystal-lang
snsei has quit [Remote host closed the connection]
snsei has joined #crystal-lang
rohitpaulk has joined #crystal-lang
snsei has quit [Ping timeout: 240 seconds]
<FromGitter> <jwaldrip> Been optimizing my router implementation. The following benchmarks compare kemal <-> orion (mine), why would the req/s be higher in orion, but the latency be higher too? ⏎ ⏎ `````` [https://gitter.im/crystal-lang/crystal?at=5a27813387680e6230d82c7c]
aroaminggeek is now known as aroaminggeek[awa
rohitpaulk has quit [Ping timeout: 260 seconds]
snsei has joined #crystal-lang
rohitpaulk has joined #crystal-lang
aroaminggeek[awa is now known as aroaminggeek
rohitpaulk has quit [Ping timeout: 255 seconds]
alex`` has joined #crystal-lang
rohitpaulk has joined #crystal-lang
snsei has quit [Remote host closed the connection]
aroaminggeek has quit [Quit: Textual IRC Client: www.textualapp.com]
aroaminggeek has joined #crystal-lang
snsei has joined #crystal-lang
<FromGitter> <yxhuvud> my guess is that you create more objects that invoke the GC more often
DTZUZO has quit [Ping timeout: 248 seconds]
<FromGitter> <yxhuvud> It would be nice if that thing showed the median latency too - averages is not that interesting for latency as the distributions tend to not make averages relevant
rohitpaulk has quit [Ping timeout: 248 seconds]
rohitpaulk has joined #crystal-lang
claudiuinberlin has joined #crystal-lang
mark_66 has joined #crystal-lang
Ven`` has joined #crystal-lang
Ven`` has quit [Client Quit]
<FromGitter> <yxhuvud> and measuring stdev for latency is utterly useless as latency is basically never having a standard distribution.
dragonkh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
aroaminggeek is now known as aroaminggeek[awa
rohitpaulk has quit [Ping timeout: 240 seconds]
rohitpaulk has joined #crystal-lang
Papierkorb_ has joined #crystal-lang
snsei has quit [Ping timeout: 255 seconds]
<FromGitter> <marin117> Hi everyone
<FromGitter> <marin117> can anybody help with creating JSON of JSONs
<FromGitter> <marin117> to be precise
<FromGitter> <marin117> JSON with array of JSONs
<FromGitter> <crisward> Just found this issue when passing bcrypt a non-bcrypt hash - https://play.crystal-lang.org/#/r/37f7 I'm guessing this is a bug WDYT?
<Papierkorb_> marin117, what have you got? What input data do you have, and what output do you expect? Any code you tried?
<Papierkorb_> crisward, that IndexError would be really surprising to me too, that's a bug
<FromGitter> <marin117> I have input from database (basic parsing as string), and I send it as response to client
<FromGitter> <marin117> I am parsing data to hash and then converting hash to json
<Papierkorb_> crisward, meh that thing doesn't do any amount of reasonable input validation :|
<Papierkorb_> crisward, thankfully crystal is Safe By Default™, but meh
<FromGitter> <marin117> kinda somehing like this
<Papierkorb_> crisward, though what's not a bug is it expected a correctly formatted string. That's what `.create` is for. It can't reasonably distinguish a hash string from a password string
<FromGitter> <marin117> and this is not working on client
<Papierkorb_> Please always attach the error message(s) you receive
<Papierkorb_> In any case, please use JSON.mapping
<Papierkorb_> It'll make that *much* easier to use, while giving you free type safety.
<oprypin> marin117, supposed to be `response.body_io.not_nil!.gets_to_end`
<oprypin> (what a terrible construct tho)
<Papierkorb_> Or just use `response.body`
<FromGitter> <marin117> @oprypin yeah I know, but hopefully this is just for now, it is just prototype version (kinda)
<FromGitter> <marin117> @Papierkorb thank you! I will try something like that
<oprypin> what, you want to get an error just for now?
<FromGitter> <marin117> kinda :D
<oprypin> understandable, have a nice day
<Papierkorb_> https://crystal-lang.org/api/0.23.1/HTTP/Client/Response.html#body-instance-method Wow that class really needs some doc-love
<crystal-gh> [crystal] ysbaddaden opened pull request #5356: Fix bcrypt hard limit on passwords to 71 bytes (master...std-fix-bcrypt-password-size-to-maximum-71-bytes) https://git.io/vbnPY
<FromGitter> <Sija> hi @all! any1 knows for when Crystal v0.24 is planned finally?
<FromGitter> <crisward> @Papierkorb I've added this to my code, to check the string before passing it. It's probably not perfect, but works for my usecase ⏎ ⏎ ``` def self.is_bcrypt(str) ⏎ str[0,4]=="$2a$" && str.size > 40 ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5a27c6e73ae2aa6b3f91f7e0]
<oprypin> :|
<FromGitter> <crisward> I'll raise an issue
encrypted has joined #crystal-lang
encrypted has quit [Client Quit]
encryptedf has joined #crystal-lang
<Papierkorb_> crisward, that doesn't belong into the BCrypt module at all
<Papierkorb_> Please don't use it on your end either.
<Papierkorb_> Guessing and Security do NOT go together
<Papierkorb_> Simply use the correct method for each use-case. You know in your code what you have anyway. If not, fix that so you do know.
<oprypin> agree
alex`` has quit [Quit: WeeChat 1.9.1]
<FromGitter> <yxhuvud> It could be a good idea to *verify* that it is indeed having the correct format somewhere though.
<Papierkorb_> Yeah that's what I complained about above
<FromGitter> <yxhuvud> ie it is good for generating good error messages, not for figuring out what to do
alex`` has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 240 seconds]
<FromGitter> <crisward> It's just a sanity check, to make sure I don't get an uncaught error when using the bcrypt lib. A bit like checking an email is valid if it has an '@' in it. It's just results in a 'your username and password have not been found'. The hashes are coming from the database so should be ok. Some had been 'imported' from elsewhere, hence the issue. The db has like 5 accounts in it, so not too concerned.
<Papierkorb_> I still wouldn't want that to even exist in the stdlibs BCrypt. There's simply no reasonable use-case outside of a one-time transfer from a legacy system.
<Papierkorb_> Those who "know security" wouldn't use it as they view it as insecure and not worthwhile. Those who "don't know security" don't understand the inherent risks of carelessly using it, which will make it easier for them to create security vulns in their authentication systems they'll inadvertently write at some point
<Papierkorb_> Even if documented, the users in the latter category tend to simply not read it. For many things I say "Their loss", but that doesn't apply if the 'reasonable' use-cases are already slim
<FromGitter> <crisward> sorry, we're talking at cross purposes. I'm not proposing we add that crap to standard lib. It's just a local sanity check I'm doing.
<FromGitter> <crisward> in the standard lib, just checking the parts.size before examining them would be enough
<Papierkorb_> Yeah for that it's fine-y, was also referring to the general case
rohitpaulk has joined #crystal-lang
encryptedf has quit [Ping timeout: 260 seconds]
rohitpaulk has quit [Ping timeout: 264 seconds]
rohitpaulk has joined #crystal-lang
DTZUZO has joined #crystal-lang
foxxx0 has joined #crystal-lang
<foxxx0> hey, what do i need to do in order to pass an Array(String) to a function?
<foxxx0> i receive the following error: error| instantiating 'part1(Array(String), Hash(String, Int32))'
<Papierkorb_> foxxx0: Your code?
<foxxx0> do i need to change something at my def part1(input, seen)?
<foxxx0> do you participate at the advent of code? it might be a spoiler! :D
<Papierkorb_> No.
<foxxx0> error is in line 36
<Papierkorb_> I don't understand what the fuzz is all about the advent of code lol
<Papierkorb_> And please the complete error message.
<foxxx0> btw: this code is converted from my ruby solution
<foxxx0> ah hm
<Papierkorb_> Quite hard to read for both ruby and crystal code. Lots of refactoring potentional in any case.
<foxxx0> it seems my vim plugin is hiding important output
<foxxx0> it's advent of code, just quick and dirty
<foxxx0> :D
<Papierkorb_> Yes, the first line only says that there's an issue. later lines point out what's the issue.
<RX14> if your vim plugin hides error output you need to stop using it lol
<foxxx0> so it seems there is no Array#find_index in crystal?
<Papierkorb_> > undefined method 'find_index' for Array(Int32)
<foxxx0> i just started doing crystal
<Papierkorb_> Yeah we call it #index
<Papierkorb_> works the same otherwise
<foxxx0> yes
<foxxx0> that's where i'm at now
<foxxx0> i need to fix my vim plugin
<RX14> it's in the Indexable and Enumerable modules
<RX14> which are included by Array
<Papierkorb_> Isn't it Enumerable#index ?
<RX14> there's Indexable too
<foxxx0> new error :D
<RX14> you have an array of integers
<RX14> and you're trying to add a new value which can be nil
<Papierkorb_> foxxx0: Your `i` can be nil, and doing `array[nil]` doesn't make sense, hence it complaining
<RX14> oh no
<RX14> yes
<RX14> it's i
<foxxx0> so i need to state "Int32 i = 0" before the loop?
<Papierkorb_> foxxx0: Ensure, preferrably when assigning `i`, it can't be nil
<foxxx0> like ||= return "error"?
<Papierkorb_> https://paste.foxxx0.de/x0rBq/crystal#n10 `#index` returns nil if nothing was found.
<RX14> it depends on your code foxxx0
<Papierkorb_> You need to handle that case when it is
<foxxx0> i need to find the max value in the Array and its index
<Papierkorb_> How depends on your need. You can `raise if i.nil?`, or `return if i.nil?` .. or default `i = foo.index{ .. } || 0`
<Papierkorb_> Yes, but what if you don't find anything?
<Papierkorb_> "Impossible with that algorithm" doesn't exist, you have to proof it to the compiler
<foxxx0> hm hm
<RX14> wow thats inefficient lol
<RX14> iterating for the max
<RX14> then iterating again to find it's index
<foxxx0> in ruby with a hash it's actually pretty fast
<Papierkorb_> RX14: I already pointed out the potentional for refactoring :P
<foxxx0> surprisingly fast even
<Papierkorb_> I mean it being slow isn't even the real problem with the code
<foxxx0> please throw feedback at me
<foxxx0> always happy to learn
<Papierkorb_> DRY would be a start
<Papierkorb_> Using enumerators instead of hand-woven while loops as second step
<Papierkorb_> as in doing stuff like `blocks.downto(1){ .. }`
<Papierkorb_> And then recheck if a standard #each, or similar, doesn't suffice
<Papierkorb_> In other words: If you're about to type `while`, stop and check your algorithm, if you actually need full control on the execution of the loop, or if one of the various #each-esque methods don't do the trick more easily
<RX14> oh wow you use += 1 in the right hand side of a ternary expression
<RX14> thats just horrible
<Papierkorb_> And it's also duplicated few lines down
<Vexatos> does the += function return the old or the new value in crystal
<RX14> new
<Vexatos> good
<Vexatos> >_>
<RX14> well duh
<Vexatos> I've seen worse
<RX14> because it's foo = foo + x
<Papierkorb_> `a += b` == `a = a + b`, thus the new one is the reasonable consequence
<RX14> and = returns the rhs
<Vexatos> actually it's it's foo = foo + (x)
<RX14> ok Vexatos
<RX14> you can go back to #WAMM now
<Papierkorb_> It's not, it's the AST.
<RX14> also this
<Vexatos> huh.
<foxxx0> you would rather use: i = ( i == (banks.size - 1) ? 0 : (i + 1) )?
<RX14> i'd rather you used an if
<Vexatos> what would that be? Like 0 if i == banks.size - 1 else i + 1
<RX14> ternary statements with mutations AND ternary statements which don't have their expression value used are terrible
<RX14> no Vexatos
<Vexatos> I don't even know crystal syntax :3
<RX14> if i == (banks.size - 1)
<RX14> i = 0
<RX14> else
<RX14> i += 1
<RX14> end
<foxxx0> yeah
<Vexatos> that looks sane
<Papierkorb_> foxxx0: I stated at the beginning, that I don't participate in the Advent Of Code, remember? Now, looking at your code, I have *no* idea what's going on. I can't infer what your algorithm is solving.
<RX14> more lines is more readable
<foxxx0> Papierkorb_: good point
<Vexatos> RX14, selene would just have i += i == banks.size - 1 and 0 or 1
<Vexatos> :3
<foxxx0> publicly visible
<foxxx0> that's the task
<RX14> yes but Vexatos thats also unreadable
<RX14> thats just bad
<RX14> lua is bad
<Vexatos> foxxx0, that task was super slow for me because I store a new copy of the array every single iteration :D
<foxxx0> Papierkorb_: and in this case the endless loop is desired until an abort condition is met
<RX14> at least you're not using bogosort to find the max Vexatos
<foxxx0> Vexatos: my ruby solution perform suprinsignly well
<Papierkorb_> And that I can't at all might either be because 1) I don't know the underlying algorithm principles or 2) the code is hard to read. 1) is always a possibility, but I guess 2) is the case. "quick & dirty" code doesn't teach nor show anything, for your or anyone. it's saying "I don't care really", in which case I wonder why one would write code in the first place. Sounds harsh, but I really dislike "quick & dirty" :)
<Vexatos> the max is
<foxxx0> performs*
<Vexatos> uuh
<Vexatos> foldl((ac, x) -> if input[x] > input[ac] x else ac end, eachindex(input))
<RX14> i hope thats in a function Vexatos
<Vexatos> hm?
<RX14> also why using index
<RX14> instead of you know
<RX14> folding over input
<RX14> like a normal fold
<Vexatos> because I needed the index of the max, not the value
<RX14> oh yeah duh
<Vexatos> literally the next line is >stack = input[pos]
<foxxx0> Papierkorb_: i hear you
<Vexatos> My solution is slow and ugly, it takes like seven seconds :I
<Papierkorb_> In what? Haskell?
<Papierkorb_> Haskell is slow
<Vexatos> Julia
<Vexatos> And julia is really fast
<RX14> lies
<Vexatos> I am pretty sure 99.9% of that is allocating thousands of arrays
<Vexatos> But I might be wrong >_>
<Vexatos> actually no, that takes almost no time at all
<Vexatos> I wonder which is the slow part
<RX14> banks.each_index.reduce(0) { |acc, x| banks[acc] > banks[x] ? acc : x } right Vexatos
<Vexatos> ooooh
<Vexatos> it's the array comparison
<Vexatos> RX14, no
<Vexatos> must be >=
<Vexatos> it always prefers acc
<RX14> why?
<RX14> like
<Vexatos> because it prefers the left-most value
<Vexatos> if it is equal
<RX14> do you need the first
<Vexatos> which is why I fold left
<RX14> max
<Vexatos> yes
<RX14> o-okay
<Vexatos> Okay, the slow part is find(stored -> stored == input, storage)
<Vexatos> i.e. going through an array of thousands of arrays to find out whether the current array already has been encountered before
<Vexatos> which is the condition for breaking the loop
rohitpaulk has quit [Ping timeout: 260 seconds]
<RX14> banks.each_index.reduce({0, banks.first)) { |(prev_index, prev_value), index| prev_value >= banks[index] ? prev_index : index }
<RX14> even faster
<Papierkorb_> Don't search, find
<RX14> banks.each_index.skip(1).reduce({0, banks.first)) { |(prev_index, prev_value), index| prev_value >= banks[index] ? prev_index : index }
<RX14> that also works
<Vexatos> I wonder if I could make that call any faster
hightower2 has joined #crystal-lang
<RX14> but at that point
<RX14> just use a loop
<Vexatos> aaand there we go
<Vexatos> reduced it from 7 seconds to 0.7 seconds
rohitpaulk has joined #crystal-lang
<RX14> def max_index(array); max = array.first; index = 0; 1.upto(array.size) do |candidate_index|; if array[candidate_index] > max; index = candidate_index; max = array[candidate_index]; end; end; end
<Papierkorb_> Mh a `Iterable#keep` would be neat which would only pass on what its blocks is truthy (or falsy) for to do `foos.keep{|x| x > 5}.map{|x| x * x}`
<Papierkorb_> Err, pass on if match, and directly return if no match
<Vexatos> Apparently find is a piece of garbage... for some reason? I replaced it with a for loop and it's an order of magnitude faster
<Vexatos> what
<RX14> Papierkorb_, you mean
<RX14> select
<Papierkorb_> No
<RX14> uhh
<Vexatos> does crystal have a macro for timing calls?
<RX14> what do you mean then Papierkorb_
<Papierkorb_> `[1,2,3,4].keep{|x| x > 2}.map{|x| x * x}` -> [1,2,9,16]
<RX14> Vexatos, Time.measure in 0.24.0
<RX14> before that you need to import benchmark
<RX14> and use Benchmark.measure
<Vexatos> like I can just throw @time in front of any block or expr
<oprypin> Papierkorb_, are you tired? lol
<Vexatos> or call
<Papierkorb_> oprypin: ?
<RX14> Vexatos, that's an optimization for a really rare thing tbh
<RX14> and - you can always write one
<Vexatos> @time is one of the most useful things in julia
<Vexatos> Makes it super easy to time individual calls to find out which one is the slow one
<RX14> Vexatos, macro time(expr); time = Benchmark.realtime{ {{expr}} }; puts {{expr.stringify}} + " took #{time}"; end
<RX14> just add the word time before an expression
<RX14> done
<Vexatos> does it also produce the number and size of allocations done?
<RX14> oh and that macro needs to capture the return value of expr
<Vexatos> rather, is there a way to do that
<RX14> no Vexatos
<RX14> you have to look at GC.stats
<Vexatos> >0.765151 seconds (56.18 k allocations: 3.444 MiB)
<RX14> cool
<Vexatos> it actually is
<Vexatos> but then again
<Papierkorb_> Didn't follow, is the same algorithm 10x faster on Cr than Julia?
<Papierkorb_> *as fast
<Vexatos> julia is 230MB in size
<foxxx0> okay
<Vexatos> Papierkorb_, no I just replaced a find() with a for loop and it became ten times faster for who knows the reason
<Vexatos> both in the same language :P
<foxxx0> this outputs "false"
<foxxx0> may someone explain that to me?
<Papierkorb_> foxxx0: Common pitfall: Hash#includes? checks for the key-value-pair, not a key. You meant Hash#has_key?
<RX14> Hash is enumerable og {k, v}
<RX14> on*
<foxxx0> Papierkorb_: ooh
<foxxx0> Papierkorb_: aha! thanks
<Papierkorb_> foxxx0: Another solution is using `Hash#[]?`, which is semantically the same if you don't have falsy values. If you're unsure, sue has_key
<oprypin> Enumerable({K, V})
<Papierkorb_> use has_key? *
<foxxx0> it works
<foxxx0> now i need to figure out why it dislikes my part2
<Papierkorb_> > in day06.cr:27: undefined method 'size' for Int32
<Papierkorb_> It tells you what's wrong right there
<Papierkorb_> > (Hash(String, Int32) | Int32 | String
<Papierkorb_> That looks kinda unhealthy
<foxxx0> yes, but i don't know why
<foxxx0> seen = {} of String => Int32
<foxxx0> isn't that explicit enough?
<Papierkorb_> you can still assign seen to a non-hash later on
<Papierkorb_> Which you apparently do
<foxxx0> oh, where is that?
<Papierkorb_> No idea? Your code
<foxxx0> maybe it's because of: result_part1, duplicate, seen = part1(input, seen)?
<foxxx0> indeed it is
<foxxx0> sweet
<foxxx0> starting to get the hang of it
rohitpaulk has quit [Ping timeout: 276 seconds]
rohitpaulk has joined #crystal-lang
<foxxx0> Papierkorb_: if you feel like it, i would appreciate another advice/feedback: https://paste.foxxx0.de/dWr2/crystal
<foxxx0> tried to implement you suggestions
<foxxx0> your*
<Papierkorb_> Choose a more descriptive name than `i`
<foxxx0> idx? or index?
<Papierkorb_> The only place `i`, `j`, ... have a place is as iterator variable in a loop
<Papierkorb_> Both are technically fine
<Papierkorb_> Your seen Hash can also use the blocks Array as key directly, no need to mess with strings
<Papierkorb_> That saves you a join and speeds up the algorithm, while retaining the original data for nice output later on
<Papierkorb_> Line 27, ruby-ism "Using array to return multiple values". In Crystal, use tuples instead.
<Papierkorb_> Why's `seen` initialized outside? Just do so in #part1 and return it later on
<Papierkorb_> The lines 12/13 are still inefficient
<foxxx0> hm
<foxxx0> i need a copy of banks as key
<foxxx0> for the hash
<Papierkorb_> #dup
<foxxx0> wow
derek-away is now known as daemonwrangler
<foxxx0> 2x speedup
<foxxx0> ideas for line 13/14?
<Papierkorb_> *banks* doesn't make sense to be defaultable, type it instead
rohitpaulk has quit [Ping timeout: 268 seconds]
<foxxx0> [] banks?
<foxxx0> or banks[]?
<Papierkorb_> what's the full type of `[] of Int32`?
<Papierkorb_> If unsure, fire up `crystal play`, and in there, ask `typeof(..)`
<foxxx0> banks of Array(Int32)?
<Papierkorb_> For type restrictions, we use `:`
<foxxx0> oooooh, crystal play looks like something i desired
<foxxx0> def part1(banks : Array(Int32))
<foxxx0> :)
<Papierkorb_> yes that's much better
<foxxx0> i will change part2 also
<foxxx0> how would this type restrictions look for "{} of Array(Int32) => Int32"?
<foxxx0> it doesn't like: "seen : Hash(Array(Int32), Int32)"
<foxxx0> full error: https://paste.foxxx0.de/iODZD/
<Papierkorb_> > no overload matches 'part2' with types Array(Int32), Hash(Array(Int32), Int32)
<Papierkorb_> You read this error like this:
<Papierkorb_> "no overload" = you provide one (or more) methods of the name "part2", but nothing of them work for you
<Papierkorb_> "with types Array(Int32), Hash(Array(Int32), Int32)" you want to pass a `Array(Int32)` as first argument, and `Hash(Array(Int32), Int32)` as second
<Papierkorb_> Under that, it shows you all overloads that are available
<Papierkorb_> Your job is now to either provide a new part2 method, or fix the call site.
<Papierkorb_> The first argument you want to pass is a Array(Int32). The only overload you provide expects a String as first argument. Clearly, those types are not the same. Hence it complaining
<Papierkorb_> In your case, you probably want to fix the part2 function to accept that array instead of a string, as the string stuff was just an artifact of your String#join from before
rohitpaulk has joined #crystal-lang
<foxxx0> ah derp
<foxxx0> yes
<foxxx0> this is actually pretty nice
<foxxx0> the compiler already prevents you from using wrong argument datatypes
<foxxx0> last question
<foxxx0> in ruby i can do something like: my_duration = Benchmark.realtime do { sleep(5) }
<foxxx0> to have a measurement with even more precision that Time.now.epoch_ms
<foxxx0> i was unable to get that to work ini crystal
rohitpaulk has quit [Ping timeout: 240 seconds]
<Papierkorb_> Haven't tried running it, but yours a bit more modified https://gist.github.com/Papierkorb/1369ba4dafcf8262e0e54dbd736ebec4
<RX14> foxxx0, it should work
<foxxx0> RX14: looks like i derped
<foxxx0> Papierkorb_: wouldn't it be smarter to define max_with_index and return a tuple?
<foxxx0> that should be more efficient
<Papierkorb_> Technically yes, but I doubt it'd be by much
<foxxx0> hm, hash access with index already is O(1) right?
<Papierkorb_> Hence I'd prefer a generic algorithm over a specialized one if I'm not out to count cycles. though the change needed for that is trivial
<Papierkorb_> banks is an array, that's O(1), also the array is small and thus (at this point) in the CPU cache already
<Papierkorb_> The only thing that costs is the branch to do the bound check
<foxxx0> def max_index(enum : Enumerable(Int32)) : Int32?
<foxxx0> that last : Int32? defines the return type of max_index?
<RX14> yes
<Papierkorb_> yes
<foxxx0> can you specify tuples there as well?
<Papierkorb_> Though we say it *restricts* the return type to that in Crystal
<RX14> yes
<Papierkorb_> Sure `... : {Int32?, Int32}`
<foxxx0> what is the style guid for functions with parameters that are >80chars line length?
<foxxx0> how do i split that to multiple lines?
<oprypin> foxxx0, write it and then run crystal tool format
<foxxx0> Papierkorb_: can't define enum inside def
<foxxx0> Papierkorb_: i guess your "enum" variable is reserved?
<oprypin> foxxx0, enum is a language keyword, yes, please use a different name
<foxxx0> oprypin: not my idea :D
<foxxx0> crystal tool format does nothing
<Papierkorb_> oh yeah
<oprypin> foxxx0, it hasn't changed your source file? then you're following the style guide
<foxxx0> yeah well
<foxxx0> a line with 140 chars can hardly be well formatted?!
<foxxx0> and it doesn't complain/change if i spread it over 4 lines
hightower2 has quit [Ping timeout: 260 seconds]
hightower2 has joined #crystal-lang
<foxxx0> the Time::Span#to_f converts to ms?
<foxxx0> or µs?
aroaminggeek[awa is now known as aroaminggeek
aroaminggeek is now known as aroaminggeek[awa
DTZUZO has quit [Ping timeout: 240 seconds]
hightower2 has quit [Ping timeout: 240 seconds]
DTZUZO has joined #crystal-lang
<foxxx0> i came up with this workaround now: https://paste.foxxx0.de/0qb56/
<foxxx0> does that look reasonable?
faustinoaq has quit [Ping timeout: 248 seconds]
rohitpaulk has joined #crystal-lang
faustinoaq has joined #crystal-lang
aroaminggeek[awa has quit [Ping timeout: 250 seconds]
faustinoaq has quit [Ping timeout: 248 seconds]
<oprypin> foxxx0, absolutely not
<oprypin> wtf
<RX14> uhh foxxx0
<oprypin> foxxx0, tried, like, documentation or something? https://crystal-lang.org/api/master/Time/Span.html#total_milliseconds%3AFloat64-instance-method
<RX14> exactly lol
daemonwrangler is now known as derek-away
<foxxx0> derp
<foxxx0> :D
<foxxx0> overlooked that
<oprypin> foxxx0, why do you even need this to be a float?
* foxxx0 facepalms
<foxxx0> i wanted higher precision that full ms
<foxxx0> s/that/than/
<RX14> we have ns precision
<RX14> use nanoseconds as an integer
<oprypin> no, don't. use time span
<RX14> he's already using timespan
<RX14> use Benchmark.realtime {} which returns a Time::Span
<foxxx0> that's what i do
<RX14> and then you use total_milliseconds/ total_nanoseconds / total_seconds with a round() call
<RX14> depending on how you want to display it
<oprypin> literally just print it
<RX14> default timespan is in seconds oprypin
<RX14> when things take ms you really don't want that
<RX14> you want to do #{ts.total_milliseconds.round(2)}ms
derek-away is now known as daemonwrangler
<foxxx0> i have printf
<foxxx0> with a format string
<RX14> :((((((((((((
<oprypin> RX14, format string is much better though
<RX14> eww
<RX14> it's cryptic and unreadable
<RX14> sure you can learn it to the point where you remember it at a glance
<RX14> but you can't expect everyone to be able to do the same
<foxxx0> well
<foxxx0> format strings are really not hard
<RX14> I much prefer the more readable solution
<foxxx0> it's not like it's regex
<RX14> uhh
<RX14> regex is way easier than format strings
<foxxx0> haha
<foxxx0> nope
<foxxx0> fmt_output = "%6s: %14s = %8d (took %8.3fms)\n"
<RX14> it's got way fewer options
<foxxx0> i suppose everyone should be able to decipher that?
<RX14> no
alex`` has quit [Quit: WeeChat 1.9.1]
<RX14> I mean I can
<RX14> doesn't mean everyone can
<RX14> or should
<oprypin> saving the result of rounding back into a float is stupid.
flaviodesousa has quit [Quit: KVIrc 4.2.0 Equilibrium http://www.kvirc.net/]
<RX14> round, ljust and rjust are maybe more explicit but a lot more readable
<oprypin> ok but round works incorrectly
<RX14> regex is just letters, ., +, *, ?, capture groups and character groups
<RX14> anything else and regex is a crutch
<RX14> well maybe {} for repeat ranges
<oprypin> i get it now https://carc.in/#/r/37g7
<foxxx0> is there a build flag to link statically?
<oprypin> there's no flag to do it, maybe you can do with many flags and much work
illyohs has joined #crystal-lang
<RX14> yes there is oprypin
<RX14> there's a --static flag
<RX14> well in 0.24.0
<RX14> it's just that nothing really supports it
<RX14> except the compiler
<RX14> and it's useless on non-alpine because glibc will never be truly static
<RX14> same with openssl
<oprypin> summary of your reply: "ackshually"
<RX14> well it's my PR
<RX14> so
<FromGitter> <bararchy> XD
Papierkorb_ has quit [Quit: Konversation terminated!]
<FromGitter> <bararchy> Found something wierd
aroaminggeek has joined #crystal-lang
<FromGitter> <bararchy> when writing specs
<FromGitter> <bararchy> ```it "print" do ⏎ code ⏎ end ⏎ ``` ⏎ ⏎ Will print the word print [https://gitter.im/crystal-lang/crystal?at=5a281a7ea2be4668286ac621]
<FromGitter> <bararchy> at least in verose (once green and once white)
<FromGitter> <johnjansen> and if you change the word?
<FromGitter> <bararchy> not printing
<oprypin> proof
<FromGitter> <bararchy> XD
<FromGitter> <johnjansen> ha
<oprypin> i mean please show proof
<FromGitter> <johnjansen> lol
<FromGitter> <johnjansen> i was about to say … that proves the opposite ;-)
<FromGitter> <bararchy> oprypin -- this does not uses --verbose
<oprypin> bararchy, ok but you still have not provided any proof
<oprypin> nor even proper instructions to reproduce it. i can't find a way.
aroaminggeek has quit [Ping timeout: 250 seconds]
<FromGitter> <bararchy> proof enough ?
<oprypin> no
<oprypin> this is happening because of `puts "hello"` btw
<FromGitter> <bararchy> ...
<FromGitter> <johnjansen> @bararchy try to isolate the simplest possible way to make this appear
<FromGitter> <bararchy> why is the word "print" get printed twice?
<oprypin> > this is happening because of `puts "hello"` btw
<FromGitter> <bararchy> puts "hello" should only print hello, not "print"
<FromGitter> <bararchy> and the green print, this is expected because of the --verbose flag
galstar[m] has joined #crystal-lang
<oprypin> i dont care dude, the cause is `puts "hello"` not the word "print"
<FromGitter> <bararchy> Oh, ok
<oprypin> this happens because this uses \r to overwrite previous results
<oprypin> but you add a newline and it cant do that anymore
<FromGitter> <bararchy> ahhhh
<FromGitter> <bararchy> a bug nontheless XD
<FromGitter> <johnjansen> @bararchy you can see this clearly if you take the @oprypin and tweek it slightly, then run that ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ you will see the same behaviour [https://gitter.im/crystal-lang/crystal?at=5a281d033ae2aa6b3f9403b5]
snsei has joined #crystal-lang
<FromGitter> <johnjansen> so the word `print` in and of itself, has no significance
<FromGitter> <bararchy> I see, it's just the "puts" that mangles the printout
<FromGitter> <johnjansen> yep
<FromGitter> <johnjansen> actually, only the fact that puts appends a `\r`
<FromGitter> <johnjansen> if you change the `puts` to `print` you will see a different result
<FromGitter> <johnjansen> do that in both cases (in the @oprypin sample) and note the difference
<oprypin> yes but you mean `\n` not `\r`
<FromGitter> <johnjansen> yep … sorry ;-)
alex`` has joined #crystal-lang
alex`` is now known as alexherbo2
aroaminggeek has joined #crystal-lang
mark_66 has quit [Remote host closed the connection]
aroaminggeek is now known as aroaminggeek[awa
snsei has quit [Remote host closed the connection]
snsei has joined #crystal-lang
snsei has quit [Ping timeout: 250 seconds]
<FromGitter> <LuckyChicken91_twitter> ```spaces = "" ⏎ text.size+1.times do ⏎ spaces = spaces + " " ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5a282a0f3a80a84b5bc4fc44]
<FromGitter> <LuckyChicken91_twitter> why is this not working
<FromGitter> <LuckyChicken91_twitter> why cant i do text.size+1.times do
<oprypin> text.size + (1.times do)
<oprypin> (text.size + 1).times do
claudiuinberlin has quit [Quit: Textual IRC Client: www.textualapp.com]
<FromGitter> <LuckyChicken91_twitter> thanks
<oprypin> 2017-08-31.log:[20:28:58] <FromGitter> <LuckyChicken91_twitter> can someone tell me why for example this is not working: `myint-1.times do`
<oprypin> ffs
<FromGitter> <LuckyChicken91_twitter> yes i know
<FromGitter> <LuckyChicken91_twitter> i forgot it again
<FromGitter> <LuckyChicken91_twitter> but this time i will remember it! i swear
<foxxx0> is there a good shard for a TUI / terminal user interface with efficient and fast (re)draws?
<foxxx0> preferably without any involvement of ncurses? :)
<FromGitter> <LuckyChicken91_twitter> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5a28327f3ae2aa6b3f949177]
<FromGitter> <LuckyChicken91_twitter> actually there are \n in this texts
<FromGitter> <LuckyChicken91_twitter> but i cant check them
vivus has joined #crystal-lang
<oprypin> LuckyChicken91_twitter, '\n' != "\n"
<FromGitter> <bew> You are comparing a Char with a String
daemonwrangler is now known as derek-away
<FromGitter> <LuckyChicken91_twitter> i already tried '\n'
rohitpaulk has quit [Ping timeout: 260 seconds]
<FromGitter> <bew> Prove it on (e.g on carc.in)
<FromGitter> <bew> Because it should work
rohitpaulk has joined #crystal-lang
claudiuinberlin has joined #crystal-lang
derek-away is now known as daemonwrangler
aroaminggeek[awa is now known as aroaminggeek
vivus has quit [Ping timeout: 258 seconds]
aroaminggeek is now known as aroaminggeek[awa
vivus has joined #crystal-lang
rohitpaulk has quit [Remote host closed the connection]
xiljin has joined #crystal-lang
Poeticode is now known as Poetichristmas
<crystal-gh> [crystal] RX14 opened pull request #5358: Version 0.24.1 (master...0.24.1-changelog) https://git.io/vbcSV
<RX14> please tell me if i've missed anything
<FromGitter> <LuckyChicken91_twitter> why is there no i4 bit integer
<RX14> because there isn't much of a usecase
<FromGitter> <LuckyChicken91_twitter> but it would still be cool
<FromGitter> <LuckyChicken91_twitter> or 2bit integer or even 1bit integer
<RX14> it's a lot of effort to add a new datatype
<RX14> and a 1 bit integer is called
<FromGitter> <LuckyChicken91_twitter> wut
<RX14> a boolean
<RX14> @LuckyChicken91_twitter it's a lot of effort to add a new integer type
<FromGitter> <LuckyChicken91_twitter> actually you just need to add the 4 bit integer and set a maximum limit and minimum limit
<FromGitter> <LuckyChicken91_twitter> theres no effort
<RX14> absolutely not
<FromGitter> <bew> RX14 you removed
<FromGitter> <bew> Grr
<RX14> ???
<FromGitter> <bew> You removed user mentions in the changelog, is it intentionnal?
<RX14> oh uhh
<RX14> not really
<RX14> my bad
<RX14> also forgot to do my `s|\[#([0-9]+)\]|[#\1](https://github.com/crystal-lang/crystal/issues/\1)|`
<RX14> actually %s|\[#\([0-9]+\)\]|[#\1](https://github.com/crystal-lang/crystal/issues/\1)| for future reference by me
<FromGitter> <bew> ah yes, that would be good too!
<FromGitter> <bararchy> RX14, wouldn't having a 0.24 milestone in the git with all relevant issues\PR's taged against it be a better way to "track" the status of a new version?
<RX14> you can't have conversations on milestones
<RX14> we have the next milestone which tracks the release
<RX14> this is an issue which happens *right before* release
<RX14> to discuss it and make sure we all agree on releasing it
<FromGitter> <bararchy> Oh, I see
<FromGitter> <bararchy> ok, makes sense. So this issue is more of a "RFC" on the new release ?
<RX14> well
<RX14> we'd have to PR in the changelog diff *anyway*
<RX14> and we have to do that before the release anyway
<RX14> so why not make it formally the place to discuss the new release
<RX14> instead of the inevitable informal discussion which would happen anyway
<FromGitter> <bararchy> ^ on multiple untracked issues
<FromGitter> <bararchy> yeha
<FromGitter> <bararchy> hahha
<oprypin> RX14, you dont need to put links to crystal/issues/\1 like you said
<RX14> yes we do
<oprypin> sdogruyol did it for whatever reason in his PR but that was never needed before
<RX14> I don't want to rely on GFM
<oprypin> thats stupid
<RX14> it's not on github in terms of being a issue or PR
<oprypin> you would be making markdown unreadable for the purpose of making links explicit but nobody clicks links in raw markdown
<RX14> I do
<FromGitter> <bew> what is "GFM"?
<RX14> and i have been
<RX14> for the last
<RX14> idk
<RX14> 15 mins
<oprypin> how is that
<RX14> by opening it in emacs
<RX14> and clicking the links?
<oprypin> there aren't even any links, what were you clicking?
<RX14> I ran s|\[#\([0-9]+\)\]|[#\1](https://github.com/crystal-lang/crystal/issues/\1)|g
<RX14> like I intended to
<oprypin> well i'm saying that's stupid
<RX14> cool
<RX14> at best it's a bikeshed oprypin
<oprypin> RX14, then what's the point of the text "#5096" ?
<oprypin> might as well wrap the whole line in the link
<RX14> so that it reads nicely when it IS rendered
<RX14> some lines have multiple PRs oprypin
<RX14> can't do that
<oprypin> it already reads nicely when rendered, you just insist on making it read horribly when not rendered
<oprypin> not to mention a ton of unnecessary work maintaining this
<FromGitter> <bew> which work? the only work is when adding, there's nothing to maintain imo
<FromGitter> <bew> @oprypin can you disable text wrapping in your editor/text-viewer/pager? this way you see properly the texts, and the long line with the link is hidden or on the right, not cluttering your view
<RX14> none of them wrap on 1080p
<oprypin> it is cluttering the view because of varying line widths
<RX14> unless you split
<FromGitter> <bew> removing links just to make it uncluttered when you're looking at the markdown is non-sense, if it's really an issue for you, configure your viewer to hide links or something
<RX14> oprypin, would you prefer "Compiler bugfixes"
<FromGitter> <jwaldrip> Is there a way to see the objects created in crystal? i.e. something equivalent of the ruby ObjectSpace object?
<RX14> no
<RX14> simpler times
<oprypin> RX14, i dont know. doesn't sound so good, now that you mention it
<FromGitter> <jwaldrip> bummer
<RX14> exactly
<FromGitter> <jwaldrip> any LLVM tools?
<RX14> for what @jwaldrip
<FromGitter> <jwaldrip> Just looking at what objects are being created
<RX14> oprypin, "compiler bugs fixed" and "documentation fixes" are in the same tense
<FromGitter> <jwaldrip> and how many there are
<RX14> it's just english being weird
<oprypin> RX14, there's no tense actually, just the object
<RX14> @jwaldrip not really
<oprypin> i see your point
<RX14> oprypin, there is, "bugs fixed" "bugs being fixed" "bugs to be fixed"
<FromGitter> <jwaldrip> Im trying to figure out why my HTTP router can do more req/s than kemal... but at the same time the response times are higher...
<RX14> there is an implicit past tense you need more words to break out of
<FromGitter> <jwaldrip> Which seems counterintuitive...
<FromGitter> <jwaldrip> Someone suggested that it could be the GC collecting objects...
<RX14> @jwaldrip i assume you benchmarked on the same machine
<FromGitter> <jwaldrip> yes
<RX14> and no it's not really unintuitive
<FromGitter> <jwaldrip> same machine
<FromGitter> <jwaldrip> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5a2845bda2be4668286bde8a]
<RX14> the requests per second is a function of work done per request
<RX14> and the latency is a function of the work done PLUS the time spent blocked
<RX14> if you simply have more write calls your latency will be much higher with little extra actual work
<FromGitter> <jwaldrip> Write calls as in `IO.write`?
<RX14> as in calls to unbuffered_write
<RX14> which is dependant on amount written and number of times flush is called
<FromGitter> <jwaldrip> hmm
<RX14> unless your write is >8192 in which case it gets complicated
<RX14> or simpler
<RX14> but it's a special case
<RX14> either way
<FromGitter> <jwaldrip> Apps for benchmarks are here
<FromGitter> <jwaldrip> Kemal does: ⏎ ⏎ ```get "/authorizations/:id" do ⏎ "" ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5a284670ba39a53f1a2ae13e]
<FromGitter> <jwaldrip> Which makes me wonder if it even attempts a write if the return string is empty.
<FromGitter> <jwaldrip> Where Orion does:
<FromGitter> <jwaldrip> ``` context.response.puts "" ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5a2846b2ffa3e3791904c1a4]
<RX14> aargh
<RX14> github dropped their latency stats on their status page
<RX14> you used to be able to see if it was github or you
<RX14> but now it's all guesswork
<FromGitter> <jwaldrip> Ah ha... okay, no `IO.write`...
<FromGitter> <jwaldrip> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5a28486bcc1d527f6bfc553a]
<RX14> wow thay're that slow?
<RX14> wait what does vanilla http::server get on yoru laptop?
aroaminggeek[awa is now known as aroaminggeek
csk157 has joined #crystal-lang
<FromGitter> <jwaldrip> let me look
<FromGitter> <jwaldrip> I have a ton of other stuff running too
<FromGitter> <jwaldrip> But they should all be relative
<FromGitter> <jwaldrip> let me do a basic http one
<foxxx0> is there something like the ruby TTY toolkit for crystal? (refering to e.g.: https://github.com/piotrmurach/tty-screen )
csk157 has quit [Ping timeout: 240 seconds]
<FromGitter> <jwaldrip> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5a285049232e79134d18a4aa]
<FromGitter> <jwaldrip> there ya go @RX14
<RX14> That's a lot slower
<RX14> Crystal doesn't really have a pay for what you use low overhead framework
<RX14> And it might well be desired
A124 has joined #crystal-lang
<Papierkorb> 'have a pay'?
<RX14> Crystal doesn't really have a "pay for what you use" low overhead framework
csk157 has joined #crystal-lang
<Papierkorb> I don't use http stuff much, but a roda clone would be much appreciated lol
<RX14> more time in the day would be appreciated
A124 has quit [Ping timeout: 255 seconds]
phase[m] has quit [*.net *.split]
asterite has quit [*.net *.split]
go|dfish has quit [*.net *.split]
Majost has quit [*.net *.split]
FromGitter has quit [*.net *.split]
ashirase has quit [*.net *.split]
dtcristo has quit [*.net *.split]
braidn[m] has quit [*.net *.split]
olbat[m] has quit [*.net *.split]
alexherbo2 has quit [Quit: WeeChat 1.9.1]
vivus has quit [Ping timeout: 276 seconds]
sija[m] has quit [Ping timeout: 240 seconds]
galstar[m] has quit [Ping timeout: 246 seconds]
tybee[m] has quit [Ping timeout: 246 seconds]
cptaffe has quit [Ping timeout: 246 seconds]
watzon has quit [Ping timeout: 255 seconds]
Renich has quit [Ping timeout: 255 seconds]
thelonelyghost has quit [Ping timeout: 248 seconds]
weston_[m] has quit [Ping timeout: 255 seconds]
byteflame has quit [Ping timeout: 240 seconds]
kp666[m] has quit [Ping timeout: 264 seconds]
TheGillies has quit [Ping timeout: 255 seconds]
ashirase has joined #crystal-lang
olbat has quit [Ping timeout: 240 seconds]
alex`` has joined #crystal-lang
vivus has joined #crystal-lang
Majost has joined #crystal-lang
FromGitter has joined #crystal-lang
asterite has joined #crystal-lang
go|dfish has joined #crystal-lang
go|dfish has quit [Max SendQ exceeded]
go|dfish has joined #crystal-lang
<FromGitter> <oprypin> we're back
<FromGitter> <unreadable> @jwaldrip there's also https://github.com/tbrand/router.cr
<FromGitter> <jwaldrip> Also uses the other radix
<FromGitter> <jwaldrip> I will have to benchmark that as well
<FromGitter> <jwaldrip> @unreadable I was actually thinking about using the method in the tree lookup as well, but implemented the HTTP constraints instead.
<FromGitter> <jwaldrip> Its a tradeoff for speed for sure, but gives you far more flexibility to do multi-method actions/routes without duplicating an item in the tree
<RX14> i think radix.cr is poorly optimized
<RX14> it's so much code
<FromGitter> <jwaldrip> RX14, I would love for you to take a look at my implementation
<RX14> wait theres 2 now?
<FromGitter> <jwaldrip> :-)
<RX14> where?
<RX14> wow thats even more code
<RX14> i didn't think it was possible to overengineer a radix tree more
<RX14> but you've managed it
<FromGitter> <unreadable> I need to know what a radix could do, but switch couldn't do it
olbat has joined #crystal-lang
olbat has quit [Changing host]
olbat has joined #crystal-lang
<FromGitter> <unreadable> I find the switch handler very clean and straight forward
<RX14> Uhh
<RX14> Be dynamic
<RX14> Lol
<RX14> You cannot add to a switch at runtimr
<FromGitter> <chuckremes> That’s why his handle is @unreadable :)
<FromGitter> <unreadable> that radis is similar with a bst, right?
<FromGitter> <unreadable> the way it works
<RX14> And you cannot radially have route params in a switch
<RX14> Easily*
<RX14> Damn autocorrect
<FromGitter> <eliasjpr> @RX14 More code does not translate to poorly optimized
<FromGitter> <eliasjpr> IMO
<FromGitter> <jwaldrip> What makes the radix implementation complex is the fact that there are dynamic parts to the tree
<RX14> It very very often does
<Papierkorb> No opinion needed: Ask a profiler.
<RX14> I don't see why having dynamic parts is hard
<FromGitter> <jwaldrip> @eliasjpr @RX14, I did borrow quite a bit of code from the original radix implementation. I just moved some things into additional classes to make things more readable.
<FromGitter> <jwaldrip> i.e. Walker && Analyzer
<RX14> If you end up in a node which is dynamic, look up how its dynamic, execute that against the route, then after that there's another radix tree describing the remainder of the route
<FromGitter> <jwaldrip> and https://github.com/luislavena/radix/blob/master/src/radix/tree.cr is more lines than my implementation...
<RX14> Its a single pointer to adding dynamism and it can be in its own class - not complicating the core loop
<FromGitter> <sdogruyol> another thing to distract @RX14 with :D
<FromGitter> <jwaldrip> RX14, I understand that, but that is covered by both radix trees
<FromGitter> <eliasjpr> Honestly my take is that we should be probably contributing the current radix
<RX14> Same
<RX14> I mean id start the algorithm from scratch but no need to complicate the interface
<FromGitter> <eliasjpr> As a community we gain more by have one solid module than multiple each with its own issue
<RX14> ^^^^^
<FromGitter> <jwaldrip> @eliasjpr, I would have, but I am doing a more complicated method of resolving the nodes
<FromGitter> <marksiemers> I think the hard part is that all parts can be dynamic or static: ⏎ `/which/part/of/this/path/is/dynamic/and/which/static`
<FromGitter> <marksiemers> Is radix the best known algorithm for routing HTTP?
<FromGitter> <marksiemers> HTTP paths
<FromGitter> <eliasjpr> urls is one of the most use for radix implementation
<FromGitter> <eliasjpr> @elorest did something quite interesting with case statements and regexs
<FromGitter> <jwaldrip> Here is the radix tree generated by the Orion implementation...
<FromGitter> <jwaldrip> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5a285c71a2be4668286c5e47]
<RX14> Does anyone know any real world router benchmark
<RX14> With real routes and real loads
<Papierkorb> Your router needs to be really crappy for it to actually slow your application down
<FromGitter> <jwaldrip> The techempower ones?
<FromGitter> <elorest> @jwaldrip Would it be possible to add the improvements back to radix, and then extend it for your purposes in a different project?
<RX14> That is nowhere near real world lol
<FromGitter> <jwaldrip> Maybe...
<FromGitter> <elorest> :)
<RX14> Papierkorb: you'd be surprised
<FromGitter> <eliasjpr> @elorest where is your take on the rounting, you had a branch somewhere with a case statement and regex
<FromGitter> <eliasjpr> Maybe you can share it here to see whats people take on that implementation
<FromGitter> <eliasjpr> it was super simple and it performs
<Papierkorb> RX14: Then those routers are crap
<Papierkorb> unecessarily being fully dynamic or whatever
<FromGitter> <elorest> I built this into the benchmark on amber_router WIP.
<FromGitter> <elorest> Using case statements works well but I assume it will break down as more routes are added.
<Papierkorb> with one case per level, why would it be that bad under real world loads?
<FromGitter> <eliasjpr> Is there any pattern matching capabilities like the ones you will find in functional languages built into crystal?
<Papierkorb> within case there is
<Papierkorb> so the most interesting part is there
<FromGitter> <eliasjpr> Gotcha
Hates_ has joined #crystal-lang
<FromGitter> <elorest> <Papierkorb>More case statements to choose from will result in slower lookup times correct?
<FromGitter> <eliasjpr> I wonder if generating a case statement file based on routes definitions if that does well
<Papierkorb> elorest, as I said, one case per level. For the normal case of having just a handful of paths there, it will be faster than doing a dynamic lookup
claudiuinberlin has quit [Quit: Textual IRC Client: www.textualapp.com]
<FromGitter> <elorest> Yeah it definitely seems faster in that case.
<FromGitter> <eliasjpr> not only that could be a solutin but it would be possible to generate case statements with regext that validates types
Hates_ has left #crystal-lang [#crystal-lang]
Hates_ has joined #crystal-lang
<FromGitter> <eliasjpr> `/somroute/:id-int32/hello/world/published_on:date`
<FromGitter> <elorest> I’m worried that with my solution, a project with 200 routes might be slower.
<Papierkorb> .. you have 200 routes in a single sub-path level?
<FromGitter> <eliasjpr> Real world thats very possible
<FromGitter> <eliasjpr> generating dynamic routes for instance
<Papierkorb> what do you mean with "dynamic"?
<FromGitter> <eliasjpr> generating routes from a DB for instance
<Papierkorb> Then that's no business for a compile-time static structure anyway
<Papierkorb> But those are local to a single level, other levels can still make use of static structures
<FromGitter> <eliasjpr> I get your point
csk157 has quit [Ping timeout: 260 seconds]
<Papierkorb> And for that, a Hash(String, ..) gets as good as it will get without doing weird things.
<Papierkorb> I'm not sure if a Trie would be better for that. even if, memory access may easily kill any time benefit from it
aroaminggeek has quit [*.net *.split]
DTZUZO has quit [*.net *.split]
kosmonaut has quit [*.net *.split]
oprypin has quit [*.net *.split]
Liothen has quit [*.net *.split]
dom96 has quit [*.net *.split]
pabs has quit [*.net *.split]
jsn- has quit [*.net *.split]
Guest34371 has quit [*.net *.split]
DTZUZO has joined #crystal-lang
dom96 has joined #crystal-lang
dom96 has quit [Changing host]
dom96 has joined #crystal-lang
oprypin has joined #crystal-lang
faustinoaq has joined #crystal-lang
<Yxhvd> I can definitely see first or possibly second level down having a lot of entries, but that is it. It could be worth having a solution that adjust the solution to how many alternatives there are
aroaminggeek has joined #crystal-lang
kosmonaut has joined #crystal-lang
Liothen has joined #crystal-lang
jsn- has joined #crystal-lang
Guest34371 has joined #crystal-lang
pabs has joined #crystal-lang
faustinoaq has quit [Quit: IRC client terminated!]
A124 has joined #crystal-lang
faustinoaq has joined #crystal-lang
<FromGitter> <jwaldrip> Rx14, the go implementation of radix is also quite large: https://github.com/julienschmidt/httprouter/blob/master/tree.go
<RX14> not for the core loop
<FromGitter> <paulcsmith> I think optimizing the router will give you very little in terms of real world performance gains once you are generating actual responses. In my tests it's been <1% of the total response time when actually generating a response or querying the database
<RX14> and they do it right: an array of indeces and an array of children - usong soa instead of aos and they use bytes
<FromGitter> <paulcsmith> Not to say it shouldn't be optimized, just that it will probably result in minimal real world performance gains
<RX14> @paulcsmith yeah I think so too
<RX14> but yet they do seem to knock off a fair bit of performance
<RX14> idk how kemal seems to do like 50% of raw HTTP::Server though lol
<FromGitter> <paulcsmith> I wonder if that's jsut from the router. I'll try some benchmarks and see if it is that or some of the middleware. Could the method override stuff or one of the other middlewares that is causing the slowdown
<FromGitter> <paulcsmith> I would bet that the 50% slowdown would trun into a <10% slowdown once you start making some db requests, rendering more complex JSON or HTML, etc. But I'm not sure. I'll try to run some numbers
aroaminggeek is now known as aroaminggeek[awa
<Yxhvd> accounting and minimizing allocation during the request lifetimes could possibly also be worth investigating
<Papierkorb> ^
<Papierkorb> You could try using trashman (I never used it myself though) to check it without a fullblown profiler
<Yxhvd> nothing like GC to kill latency percentiles and throughput.
<RX14> if it kills throughput why are we within like 30% of these hyperoptimized web frameworks which have had man years put into them on frameworkbenchmarks
<RX14> when our HTTP server is "lol use string.split who cares about allocating this extra array"
<RX14> it's a myth
<RX14> latency sure
<RX14> throughput, nah
<Yxhvd> depends on heap size. Perhaps not relevant on these small heap sizes.
<Yxhvd> at some heap size point you need generational GC to not suck, but I've seen 30s pauses even with that (with a long lived heap that was huge, and a zillion threads).
<RX14> 30s pauses?
<RX14> thats ridiculous
<Papierkorb> Is there a stresstest for boehm?
<Yxhvd> That is what you can get if you have a huge heap and really long lived objects and are running really close to the memory limits on your system.
<Yxhvd> (this was java btw)
csk157 has joined #crystal-lang
csk157 has quit [Ping timeout: 240 seconds]
aroaminggeek[awa is now known as aroaminggeek
<FromGitter> <unreadable> would there be a significant performance between gc crystal and self managed memory crystal?
<Papierkorb> what's written in doesn't matter much. What does is its algorithm/data structure in practical terms, and what it "knows"/it can work with in theoretical ones
<oprypin> that would not be crystal
<FromGitter> <unreadable> that would not answer my question though...oO
<Yxhvd> unreadable: depends on how much memory you have. GCs tend to have less overhead when they are allowed to use a little more memory than absolutely needed.
<FromGitter> <unreadable> how may I PM you oprypin?
<oprypin> irc, email, i dunno
<oprypin> why though
<FromGitter> <unreadable> well, sfml based stuffs
<FromGitter> <unreadable> but don't wanna make offtopic
<FromGitter> <unreadable> there's actually 1 stuff that's messing me up
<FromGitter> <unreadable> applying shader on a shape doesn't use the shape as canvas, it'll take the window instead
<FromGitter> <unreadable> not sure if it's because gl_position or the way I pass the resolution uniform oO
<oprypin> unreadable, i don't have anything to add other than https://oprypin.github.io/crsfml/tutorials/graphics/shader.html#using-a-shader
<FromGitter> <unreadable> I've actually came across that gitpage, but thought it's the same as the github/sfml one
<FromGitter> <unreadable> thanks
alex`` has quit [Ping timeout: 276 seconds]
<oprypin> but i've never used shaders other than copying the official example
<FromGitter> <unreadable> I like them because it gives me a lot of control and they're actually hard
<FromGitter> <unreadable> not too**
<FromGitter> <paulcsmith> Just benchmarked raw crystal and got about 111k requests. Added a router with 1 route (to keep it even) and got 108k. Not super scientific, but my assumption is the router doesn't have that big of an impact.
<FromGitter> <paulcsmith> I did another test for just the router. Added 3000 routes. Matched against 7000 routes. Finished in 7.1ms
<RX14> @paulcsmith yeah honestly i didnt think it was that high
<RX14> but somehow the frameworks SUCK
aroaminggeek is now known as aroaminggeek[awa
<FromGitter> <unreadable> raze seems to do pretty good
<RX14> i uhh
<RX14> never heard of that one
<RX14> wow
<RX14> it does stuff right
aroaminggeek[awa is now known as aroaminggeek
<FromGitter> <unreadable> well, it's not really that well mantained
<RX14> shame
Hates_ has quit [Quit: Connection closed for inactivity]
<FromGitter> <unreadable> We
<FromGitter> <unreadable> I
<oprypin> uh what
<FromGitter> <unreadable> I think it's not needed
csk157 has joined #crystal-lang
<FromGitter> <unreadable> The mobile keyboard kills mw
<FromGitter> <unreadable> Me
csk157 has quit [Ping timeout: 264 seconds]