Earlier quoted context omitted.
High performance is a very vague terms now days, there are company that have Google scale problems that don't use C++ as main language ( Nerflix Uber ect ) any modern runtime can do "high performance" especially for backend applications. YouTube primary language is Python for instance.
Netflix OK but Uber? They did 4 billions rides in 2017. Thats naivly about 130 rides per second with nice parallelism due to locality of the physical rider. That's not an insane amount of data crunching.
Practices for writing high-performance Go
81–90 of 102 posts
Re: Practices for writing high-performance Go
#82Earlier quoted context omitted.
It is a trait inherited from the C culture, although in C it is even worse, micro-optimizing every line of code as it is being written. A C dev would start cold sweating has s/he types virtual , or operator something ().
Actually C programmers frequently use dynamic dispatch - even in the Linux Kernel for example. They just like to be explicit about it.
Re: Practices for writing high-performance Go
#83any thoughts on whether to use values or pointers to large structs? in practice I haven’t seen any major performance overhead when passing values about.
Almost all types that could hold a lot of data have reference semantics, so if you have a struct with a large slice, or a large map, all of the actual data is going to be on the heap, and not affect copy performance.
The only time you might want to consider using a pointer to improve copy performance is if you have lots of non-heap-allocated data in your struct, and in practice the only way that happens is via large arrays. That is, e.g. `[8192]string`, and not simply `[]string` (which is an efficient slice). But you should never do it preemptively, you should always benchmark both styles and only switch to pointers once you have proof it's meaningfully affecting performance.
Re: Practices for writing high-performance Go
#84Earlier quoted context omitted.
How would Rust compare?
The benchmark game puts c, rust, and c++, in that order, roughly on par in performance, with go being about 2-3x slower. No idea if that's accurate. Sampling bias means people who like performance are optimizing the languages used for performance, and people who just like to get something working quit after the first benchmark in go or python is finished. https://benchmarksgame-team.pages.debian.net/benchmarksgame/..…
regexredux program is outlier in Rust, because replacement of a regex in string is slower in regex crate, because author of regex crate chose to implement safer, but slower algorithm. To fix this, regex crate must be updated or replaced. I spent two weekends on this.
[1]: https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Re: Practices for writing high-performance Go
#85Earlier quoted context omitted.
> Who by the way runs applications on a 88 core server, why would you so they instead of splitting that into smaller chunks. Graph analysis and/or routing, for one. Distributed Dijkstra is pretty impractical (the optimal lower bound on the number of messages required equals the number of edges in the graph!) For example, I don't work for Google, but I can pretty much guarantee you that an individual Google Maps routi…
I think you're ignoring caching/preprocessing in your analysis.
Re: Practices for writing high-performance Go
#86Earlier quoted context omitted.
That's ... not helpful. I already profile and profiling indicates that allocations are slow and sweeps are fast. Go's optimization for this is escape analysis which is a best-effort attempt to put things on the stack. Because the stack analysis is naive (which isn't necessarily a bad thing), it means lots of things are still allocated on the heap, and those are the allocations I'm referring to.
The bigger issue is usually stack vs heap allocation and it’s hard to reason about that. But the good news is that unlike a JIT system you can actually pretest golang escape analysis. Look at the -m gcflag to see what is escaping, then see if that is where the allocation hotspot is. If so see if you can get the escape to happen where you want. Otherwise you need to go no allocation. Notice that go actually gets _wors…
I don't think it's especially hard to reason about in the main cases, and when you're unsure (as you mention) you can actually print out the escapes. Would be really interesting to have an editor that would show you where things were escaping (although that could easily lead to premature optimization).
Re: Practices for writing high-performance Go
#87Earlier quoted context omitted.
Actually C programmers frequently use dynamic dispatch - even in the Linux Kernel for example. They just like to be explicit about it.
A search on comp.lang.c archives might reveal other points of view.
Re: Practices for writing high-performance Go
#88Earlier quoted context omitted.
Disagree. I can write a server in C++ that, with careful thought and a bit of planning, will be able to exploit the resources of the kind of 88-core dual-socket machines that are mainstream today. No amount of planning will allow me to write a Go program that does the same thing on the same machine. Small amounts of concurrency might seem easy in Go but lots of concurrency is hard.
You're talking a about a very specific scenario, out of the box Go is off course easier than C++ for concurrency. Who by the way runs applications on a 88 core server, why would you so they instead of splitting that into smaller chunks.
https://www.nextplatform.com/2017/06/22/casing-hpc-market-ha...
Although they cost a ton, there were at least two reasons to like NUMA machines:
1. You program them much like multithreaded machines instead of message passing like MPI. You do need to account for locality. There's OS, library, and documentation support for handling that, though. Porting a multithreaded library to NUMA is much smaller problem than clustering it.
2. A massive amount of memory with lower-latency access than on clusters. If your data is in memory, it's much faster than if it's being moved in and out of memory. Then, when it is moved, it's moved faster. Low-latency reduces the damage of many smaller copies, too.
For such reasons, I always wanted a SGI or Cray machine. Modern, multi-core machines with plenty of RAM are good enough for most of my purposes, though. I do plan to do some model-checking of software in the near future. The amount of RAM used grows exponentially or something like that with the size of the program. Small ones already use GB of RAM in the analyses. Some are getting parallelized a bit. Obviously, 88 cores with 100+GB of RAM could be pretty useful if handling programs twice or three times as large. :)
Btw, there are also languages designed specifically to take advantage of parallelism in many HPC situations. Like Go, they were intended to let you describe the algorithms in a high-level way with the compiler synthesizing efficient implementations for everything from multi-cores to NUMA to clusters. That's the theory. The best one from my prior research was Chapel. Then, there's simpler ones for stuff like data parallel with Cilk being an example.
https://en.wikipedia.org/wiki/Cilk
ParaSail was a recent one with interesting design. I'm not sure what its current status is in terms of usability.
https://www.embedded.com/design/programming-languages-and-to...
Re: Practices for writing high-performance Go
#89Earlier quoted context omitted.
A search on comp.lang.c archives might reveal other points of view.
Are you trying to counter an argument based on relevant practice (the Linux kernel) with a newsgroup from the 90s? Without even giving a reference?
And yes, I am. I don't care about earning HN brownie points just to prove something that will be hand waved anyway.
Re: Practices for writing high-performance Go
#90Earlier quoted context omitted.
Honestly with the attitude that the Go authors treat their users I don't know why anyone tries to write high performing code in that language. C++ is there, after all. I work in C++. I'm sometimes surprised at the way C++ treats its users. There seems to be a culture of pre-optimization. It's hard to write the most abstract application code without constantly thinking about performance under the surface. That's baked…
C++ is unique in that it aims to be feature-rich, while preserving at much as possible the property of if you don't use it, you don't pay for it . It breaks its own rule occasionally -- RTTI, exceptions, [0] standard library machinery with always-on thread safety -- but the C++ folks go to extreme lengths in the name of performance. There's no small irony in the way embedded folks write off C++ as too heavyweight, gi…
Visual basic had a Replace() function back in 1998, to replace substrings. C++ now has many amazingly advanced high-level features, but still no built-in way to replace a substring. I don’t think I needed to write my own string replacing function in any other language I used (I’ve been programming for living since 2000).
I like C++ and use it a lot. But these seemingly small issues with its standard library escalate quickly. String handling, IO, localization, date & time, multithreading before C++ 11, many standard collections, and other parts are just not good enough. I pretty much stopped writing complete apps in C++, nowadays I’m using C++ for dll/so components I consume from higher-level languages like C#, Python or golang. And when I do, I often choose to ignore large parts of the standard library in favor of alternatives from atl, eastl, or my own ones.