Hacker Newsnew | past | comments | ask | show | jobs | submit | j03b's commentslogin

The takeaways in this article are much more why Go's memory model becomes difficult at scale. When you're dealing with memory at Discord scale garbage collection is hard, for example on the mentioned Discord microservice:

> There are millions of Users in each cache. There are tens of millions of Read States in each cache. There are hundreds of thousands of cache updates per second.

This is something that is probably never going to be hit locally in the development toolchain. You can certainly prefer the Rust memory system to Go and have that be a valid reason to use Rust over Go for something like dev toolchains, but you're not going to hit scale problems like those mentioned in the article.


Not just at scale, Go doesn't make it obvious when an allocation is on the heap or stack. The escape analysis can change (hopefully without regressions) from version to version of Go, and that can mean performance regressions can happen. It also means small refactors risk de-optimizing code without an obvious reason why that would be the case.

I think more engineers are becoming skeptical of optimizing compilers with that sort of implicit, potential "spooky action at a distance" where nonlocal code can cause performance regressions.

In Haskell, laziness and iterator fusion can do the same thing. Nonlocal code can cause local expressions to compile differently, resulting in - from an engineer's POV - nondeterministic performance, memory usage, GC pressure. "Space leaks" can also occur, again, due to nonlocal effects.

In JavaScript, the JIT can similarly cause local regressions due to nonlocal code. A single expression deep in a call stack mutating an object can result in it no longer fitting an optimized "shape", resulting in function deoptimization.

Just say no to spooky action at a distance in programming languages, in my opinion. It leads to tremendously difficult to debug regressions.


> the escape analysis can change (hopefully without regressions) from version to version of Go, and that can mean performance regressions can happen.

Because it's not the case with Rust or any compiled language? LLVM has shown regressions wich is what Rust uses to compile code.

2sec search on google: https://github.com/rust-lang/rust/issues/24194


Of course there have been regressions, but the semantics of the code don't typically change. A "dead heap allocation", or removing an unused call to malloc, is an interesting example but I think you'd be hard pressed to find a case where it caused a massive performance regression.

I think there may be some edge cases (constant folding, dead code removal) of course, but a change to LLVM cannot cause the 3 sorts of changes I identified in Go, Haskell, and JavaScript.


>Not just at scale, Go doesn't make it obvious when an allocation is on the heap or stack. The escape analysis can change

I thought heap allocations are only triggered by taking pointers, i.e. using reference semantics (including casting to interface and calling a method whose receiver is by-ref)? If I'm careful to only use variables by-value (for types that can afford it, i.e. excluding map/array), what else can trigger heap allocation?


Making a closure usually requires allocation. For example:

    package main

    import "fmt"

    func main() {
        closure := make_closure()
        fmt.Println("closure():", closure())
    }

    func make_closure() func() int {
        x := 1
        return func() int { return x }
    }
This prints:

    $ go run main.go
    closure(): 1

If x were allocated on the stack, it would get nuked after we returned from make_closure(). In Rust you could move x to the closure, but I think in this Go example x would be heap allocated, assuming the Go compiler doesn't notice it can inline all of this and avoid allocating. Maybe assume a more complex example with a struct that had to be computed via a function argument or something :)


Oh yes, closures too. Coming from C++ background, you kinda intuitively understand when things escape and when they don't, because you assume that Go would implement it in the most straightforward way (like it usually does), and in the case of closures, heap-allocating a captured variable is the simplest implementation (just let GC handle it!) considering the implicit reference semantics (that you can change "x" anywhere outside of the closure and it should be immediately visible in the closure, too). I.e. assume the worst (and don't expect Go to do some clever special-casing similar to move semantics in C++/Rust), and it's often the right answer :)


I don't know, building JavaScript things involves similar orders of magnitude.


They're focusing on Ethereum as far as I'm aware because NFTs are pretty popular on the Ethereum blockchain, and the two providers are both for Ethereum (MetaMask solely, and WalletConnect supports a lot as far as I understand)


While waiting for my query to generate, I was graced with "Hacker News", felt it was worth sharing back to this thread :)

https://imgur.com/a/OKW411E


I got something more ominous for "hacker news": https://i.ibb.co/hYVPh6k/hacker-news.jpg


You can request a copy from ICANN through the Centralized Zone Data Service (CZDS). It's a pretty neat service and will give you access to zone files for a few months, you just need to file a request to one/multiple TLDs you are interested in seeing.

Sometimes larger TLDs take a bit longer to respond to requests, whereas some others automatically accept all requests.

https://www.icann.org/resources/pages/czds-2014-03-03-en https://czds.icann.org/home


Significantly better, yes, I've never felt like String methods were missing while using Elixir, they've also got some goodies like Jaro distance right in the stdlib. Docs on Elixir strings are here, plenty of methods: https://hexdocs.pm/elixir/1.12/String.html

This getting started guide also covers some more examples of working with strings (vs. charlists, the erlang string type, which are described at the end): https://elixir-lang.org/getting-started/binaries-strings-and...


This tool is great! Ran through all these checks and deployed them to our cluster the other day.

Immutable fs & non-root is easier than I thought to deploy with k8s, going to be looking into privilege drops this week too.


thanks a lot! let us know if you have any comments or ideas


Seems to be using the same format as https://qifi.org/, which lists supported devices, but of course due to the lack of native QR on most Android devices it's per-app rather than per-phone.


It's 2021 and Android still has fragmented QR scanning.


I don’t get it… is it that every single android oem makes their own camera app? Or did google choose to just not have barcode/qr code as part of the default camera app?


Cloudflare Workers are billed separately, 100k requests/day on their free plan.

https://developers.cloudflare.com/workers/platform/limits#wo...


I had a play around with the Browser SSH terminal a few weeks ago, as well as getting actual hosts setup I managed to get ssh-chat[1] working on there which was fun. (see: https://twitter.com/JoeBanksDev/status/1382836730651410433)

The feature that interests me is the auditable portion of it, MITM recording of SSH & RDP sessions sounds very useful.

From the blog post announcing this [2]:

> Cloudflare Zero Trust Apps will record the screen of any session, batch the recordings in intervals, and send them to a storage location you have configured. We’ll be adding structured command logging and keyboard input to this flow as well.

[1] https://github.com/shazow/ssh-chat [2] https://blog.cloudflare.com/browser-ssh-terminal-with-auditi...


Yes, it does.

If you traceroute to any of the announced prefixes you'll see that you enter HE space (but as far as I know won't ever get a ping to the destination IP).


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: