Linus Torvalds on Garbage Collection (2002) - <AUTHOR> http://gcc.gnu.org/ml/gcc/2002-08/msg00552.html <comment><USER2> Shortly before Linus wrote this article in 2002, I wrote an XML-RPC library in C that used reference counting. By the time I was done, I'd written 7,000+ lines of extremely paranoid C code, and _probably_ eliminated all the memory leaks. The project cost my client ~$5K.

The standard Python xmlrpc library was less than 800 lines of code, and it was probably written in a day or two.

Was my library about 50 times faster? Sure, I could parse 1,500+ XML-RPC requests/second. Did anybody actually benfit from this speed? Probably not.

But the real problem is even bigger: Virtually every reference-counting codebase I've ever seen was full of bugs and memory leaks, especially in the error-handling code. I don't think more than 5% of programmers are disciplined enough to get it right.

If I'm paying for the code, I'll prefer GC almost every time. I value correctness and low costs, and only worry about performance when there's a clear business need.

<comment><USER3> ~$5k for 7 KLOC of bug free C code is a steal, that's impossible to do in less than a couple of months

<comment><USER4> It's nearly impossible to do in any timeframe. I can think of perhaps two examples in human history where I think it's been done: qmail and seL4. And there may still be bugs in qmail. There may be a few other non-public projects that have achieved less than one bug per 7000 lines of C, but probably not more than one or two.

<comment><USER5> <http://www.dt.e-technik.uni-dortmund.de/~ma/qmail-bugs>

There are also some DNS-related bugs that are not on this list.

<comment><USER4> Thanks! I hadn't seen those, although I knew of 1.4. I think 1.1, 1.3, and 1.4 are actual bugs, if the reports are accurate; I'm pretty sure Dan disagreed with Wietse about 1.1. Three bugs in about 15000 lines of code doesn't quite rise to the level of less than one bug per 7000 lines of code, so maybe that's only been done once, in seL4.

What are the DNS-related bugs?

</comment></comment></comment></comment></comment><comment><USER6> Reference counting is GC; a poor form if it's the only thing you rely on, but it is automatic memory management all the same.

Generational GC will frequently use the (L2/L3) cache size itself as its smallest generation, meaning it shouldn't suffer from the pathologies talked about by Linus here.

What GC really gives you, though, is the freedom to write code in a functional and referentially transparent way. Writing functions that return potentially shared, or potentially newly allocated, blobs of memory is painful in a manual memory management environment, because every function call becomes a resource management problem. You can't even freely chain multiple invocations (y = f(g(h(x)))) because, what if there's a problem with g? How do you then free the return value of h? How to you cheaply and easily memoize a function without GC, where the function returns a value that must be allocated on the heap, but might be shared?

Writing code that leans towards expressions rather than statements, functions rather than procedures, immutability rather than mutability, referentially transparent rather than side-effecting and stateful, gives you big advantages. You can compose your code more easily and freely. You can express the intent of the code more directly, letting you optimize at the algorithm level, while the ease of memoization lets you trade space for speed without significantly impacting the rest of your program. Doing this without GC is very awkward.

GC, used wisely, is the key to maintainable programs that run quickly. You can write maintainable yet less efficient programs, or highly efficient yet less maintainable programs, easily enough in its absence; but its presence frees up a third way.

<comment><USER7> GC code runs differently depending on the code running around it. It causes the code to be non deterministic, and introduces a side effect.

I've written code in a reference counted language(python) which processes about a gigabyte of data per second from the network, with hard real time requirements - all on one machine with multiple cpus/cores. The code is fully unit tested, doc tested, and functionally tested. It's also short, runs on multiple platforms and has been maintained by other people than myself. My personal experience is that you can write highly efficient maintainable code with reference counting.

Reference counting manages memory automatically for you, but it also lets to manage memory manually when needed too. For many situations, it's the best of both worlds.

<comment><USER8> Did you compare the performance of Python with that of other languages that do use GC (e.g: Haskell)?

</comment></comment></comment><comment><USER9> > _A GC system with explicitly visible reference counts (and immediate > freeing) with language support to make it easier to get the refcounts right > [...]_

To be a little pedantic on the subject, such a system (reference counting and immediate freeing) is a form of automatic memory management, but it is not GC in any way. Garbage collection implies that the system leaves _garbage_ around, which needs to be _collected_ in some way or another. The usual approach to refcounting releases resources as soon as they are no longer required (either by free()ing immediately or by sending it to a pool of unused resources), thus doesn't leave garbage around, and doesn't need a collector thread or mechanism to.

There are partial-GC implementations of refcounting, either because items are not free()d when they reach zero references, or to automatically detect reference loops which are not handled directly.

I agree with Torvalds on this matter. GC as it is promoted today is a giant step that gives programmers one benefit, solving one problem, while introducing a immeasurable pile of complexity to the system creating another pile of problems that are still not fixed today. And to fix some of these problems (like speed) you have to introduce more complexity.

This is my problem with GC. I like simplicity. Simplicity tends to perform well, and being simple also means it has little space for problems. Refcounting is simple and elegant, you just have to take care of reference loops, which also has another simple solution, that is weak references. I can teach a class of CS students everything they need to know to design a refcounting resource management system in one lesson.

GC is the opposite: it is big, complex, and a problem that the more you try to fix it, the more complex it becomes. The original idea is simple, but nobody uses the original idea because it performs so badly. To teach the same class how to design a GC system that performs as well as we expect today, an entire semester may not be enough.

<comment><USER10> _I agree with Torvalds on this matter._

In a way, I do as well.

 _GC as it is promoted today is a giant step that gives programmers one benefit, solving one problem, while introducing a immeasurable pile of complexity to the system creating another pile of problems that are still not fixed today. And to fix some of these problems (like speed) you have to introduce more complexity._

There are plenty of contexts where speed is a non-issue. In those cases, GC has been a huge win. The conceptual simplicity is the important part. The cost of the resources that would be saved with explicit and optimized memory management would be far outweighed by the resources required to implement such things.

 _The original idea is simple, but nobody uses the original idea because it performs so badly._

This is simply not true.

In the context of IO-bound enterprise systems, I've seen generational GC perform admirably, almost magically. As a lark, I've put infinite loops into such apps that do nothing but allocate new objects, and unless you are doing an exceptionally intense operation, you couldn't tell the difference. Properly tuned generational GC can be a truly fantastic seeming thing!

However, I will agree that the concerns Linus highlights are real, and that refcounting systems, like the one in iOS are by far better choices in many contexts.

EDIT: The above system I victimized, I only victimized in the TEST environment, but it was populated with something like 2-week old production data. The application in question is a traditional client/server desktop app used by a major energy company and had 800 active users at the time, handling millions in transactions every minute.

IDEA: If someone had an augmented ref-counting system with a runtime containing an optional cycle-detector and something like LINT but for the runtime reference graph, one would get most of the benefits of GC with the efficiency of the ref-counting system. I half expect someone to tell me that this already exists for Python.

<comment><USER4> > I've seen generational GC perform admirably, almost magically. As a lark, > I've put infinite loops into such apps that do nothing but allocate new > objects

While I agree that generational GC can perform spectacularly well, what you're describing is close to the case it's optimized for, not close to its worst case. The worst case is that you allocate lots and lots of small objects and then write a pointer to all of them into a tenured garbage object.

> I half expect someone to tell me that this already exists for Python.

Yes, that's how Python works, except that I don't know what you mean by "something like LINT but for the runtime reference graph."

<comment><USER10> _While I agree that generational GC can perform spectacularly well, what you're describing is close to the case it's optimized for, not close to its worst case_

Here's the thing: Most of the rest of the app was rather close to the case it's optimized for.

 _I don't know what you mean by "something like LINT but for the runtime reference graph."_

Something that tells you that you've created a reference graph with a cycle, you have a memory leak, or that you're using references in some other stupid or suboptimal way. I'm not even sure if there's a way to automatically detect anything like the last category, though the first two are certainly detectable. Basically, you take most of the infrastructure of GC, and you just turn it into a runtime advisor to warn devs and testers of mistakes.

<comment><USER4> Great Circle commercialized the Boehm collector back in the 1990s, and I seem to recall that most of their customers were using it to tell them when they had a memory leak or reused freed memory, not to remove the need for reference counting altogether. But it didn't tell you about cyclic references, unless they resulted in a memory leak.

</comment></comment></comment></comment></comment><comment><USER11> We should _really_ encourage eachother to put the date in the title when submitting old articles to HN. It's a total brainf*k to read through the entire article, and not realize the context it was in.. or to just glance at the title and assume the topic is a current one. Just saying.

[Edit] Not that I have a problem with older posts, btw.. I actually really like them most of the time. But the date would give everyone a better opportunity to evaluate whether they want to read the article, and would be reading it with reasonable context.

<comment><USER12> Is it just me, or does the title say (2002) to give you context?

<comment><USER11> That was added later (presumably in response to this comment).

</comment></comment></comment><comment><USER13> It's 2011, FFS. This kind of mindset is really self defeating in the long term. Sure, hand optimizing is better. Having a gazillion lines of shit legacy code and technical debt to fix because you hand optimized for the 90's, it's not so great. I'll keep my GC and sip a Mohito on the beach, while Linus keeps on fixing Linux's "optimizations" ten years from now.

<comment><USER14> The alternative to a GC is not "hand optimizing". There are several patterns such as reference counted memory and RAII that are far from complex to use.

If you've written any data intensive application you know that a GC doesn't solve memory issue. It's just a different strategy.

<comment><USER13> It's a strategy _I_don't_need_to_concern_with_ :-)

</comment></comment></comment><comment> loup-vaillant So. Programs that use Garbage Collection tend to be slow.

Cause: Hardware don't like it.

Solution: fix the hardware?

Seriously, I'm afraid we're stuck in a local optimum here. It is as if machines are optimized for the two dominant C/C++ compilers out there, and we have then to optimize our program against that, closing the loop. Shouldn't compilers and hardware be designed hand in hand?

<comment><USER15> I think you're referring to the following paragraph:

 _One fundamental fact on modern hardware is that data cache locality is good, and not being in the cache sucks. This is not likely to change._

However, this did not happen to please the "two dominant C/C++ compilers". The reason is much more fundamental:

One of the most expensive parts of the hardware is memory, and fast memory is a lot more expensive to produce than slower memory. So we have the choice between using the same (and thus slow) memory throughout the system, or combining different kinds of memory so that at software has at least the _chance_ to run faster. This is a fundamental issue, and the only thing you can do is trying to find the optimal share for each kind of memory.

But no matter how well you choose: software will only be able to exploit this if it is designed for locality.

If you can fix that (i. e. if you can find a cheap way to produce gigabytes of fast memory that makes chaches obsolete) the current compilers won't stop you from exploiting it: The code that is optimized for locality will still run as fast, and the code that can't be optimized for locality will run orders of magnitudes faster.

So we aren't in a local optimum at all. You can still optimize further "just" by producing faster and cheaper hardware.

<comment><USER4> _One of the most expensive parts of the hardware is memory, and fast memory is a lot more expensive to produce than slower memory. So we have the choice between using the same (and thus slow) memory throughout the system, or combining different kinds of memory so that at software has at least the_ chance _to run faster. This is a fundamental issue, and the only thing you can do is trying to find the optimal share for each kind of memory._

Although all modern high-performance (edit: I mean non-embedded- microcontroller) computers work this way, it's not the only possible way. The Tera MTA takes a different, cacheless approach.

First, the problem with modern RAM in desktop machines is not that it sucks at _bandwidth_. You can get your bandwidth arbitrarily high by multibanking. Multibanking requires more buses or point-to-point links, but that's a tolerable cost.

The problem with modern RAM is that it sucks at _latency_ , compared to what the CPU would like. Well, what do you do about latency? You make your requests earlier, and make sure you have other things to do in the meantime, when they get back. The Tera did this by having 128 sets of registers – 128 hardware threads — and switching to the next thread on every cycle. That means that, if all the thread slots were full, every thread only executed an instruction every 128 cycles, which is plenty of time to hide the latency of a slow memory fetch, as long as the memory bandwidth was adequate.

So basically every thread gets to pretend that it's running on a machine with zero-latency RAM — memory that's as fast as the registers. And pointer-chasing becomes as fast as looping over an array.

There are some other advantages to this design. Pipelining logic is very simple, because unless your pipeline gets insanely deep, you never have two instructions in the pipeline from the same thread, so you don't have register hazards.

(Cache is still beneficial in such a design, since it reduces the bandwidth that the links to main memory need to support. But the Tera didn't use it.)

I don't really understand why the Tera MTA failed in the market, and I suspect the problems were commercial rather than technical — customers had to take a big risk by porting their software to an unproven HPC platform, a platform whose performance characteristics were completely unlike anything else in the market (and unlike anything you can buy today). So customer uptake was insufficient to provide the cash flow needed to keep updating the design to keep up with Intel and AMD.

The _technical_ reason such a design might fail would be if the silicon resources needed to support an entirely independent core were comparable to the silicon resources needed to support a hardware thread. Consider the GreenArrays GA144 chip: 144 independent cores, each with a tiny amount of independent RAM, on the same chip. Such a chip will be at least as fast as a chip with 144 independent register sets, but a single execution pipeline — in the worst case, it's bottlenecked on getting data out of RAM, and only one of its cores is usable, making it just as fast, while in the best case, it runs 144 times as fast. So a chip with 144 register sets needs to be _cheaper_ — i.e. smaller — than the GA144. (Well, or easier to program, but presumably you can use more mainstream multicore chips to prove the example instead.)

<comment><USER16> Isn't there a much simpler reason - that programs are generally single- threaded? I imagine it would take a lot of work to port basic tools like a web browser to such an architecture without it running much slower. A lot of applications do little parallelizable number-crunching, but a lot of branching and sequential operations. How could you make parsing XML or HTML fast on this? What about a text processor or a compiler?

<comment><USER4> It's true, if Intel could make a single processor core that went eight times as fast on single-threaded code, they would do that instead of making eight- core chips, unless the cost difference was horrific. But they can't, so if you want your code to go faster, you have to find a way to parallelize it.

This started happening in earnest about 20 years ago in the supercomputer market, which is where the Tera was sold. About 10 years ago, it started happening in desktop CPUs (check out Herb Sutter's article about "the end of the free lunch") and now it's starting to happen in embedded microcontrollers, with the Parallax Propeller and the GreenArrays chips.

As it happens, the Tera didn't lose to faster single-threaded supercomputer CPUs. By the time the MTA came out, even the most stalwart defenders of the fast-single-threaded-performance approach, like the Cray SV1 and the NEC SX-5, had succumbed to the necessity of CPU parallelism. But the approach that was taking over the supercomputer market at the time was actually far _more_ parallel, and far more difficult to program efficiently --- NUMA machines and then Beowulfs.

So that's why I don't think it was single-threaded programs that made the Tera fail in the supercomputer market.

The question of how to meaningfully parallelize XML and HTML parsing, compilation, text processing in general, and web browsers are very interesting indeed. It's not obvious how to do it, but it might turn out to be tractable. A group at Berkeley was doing some research on it in 2007 and 2008: <http://www.eecs.berkeley.edu/~lmeyerov/projects/pbrowser/>

<comment><USER16> My point was not aimed at the Tera specifically, but rather at this architecture as a solution to the memory problem in general. As you say, supercomputers have been using multi-threaded code for a long time now, so it's not a technical problem for this case, but it can be for the kind of applications 'regular users' may need.

Thanks for the references. I'm in embedded systems but I hadn't heard of the Parallax Propeller before, it's an interesting architecture.

<comment><USER4> I suspect that the killer feature of Tera-like architectures for embedded systems could be their determinism. Embedded microcontrollers like the LPC2100 series are starting to get caches, branch prediction, and the like, and that makes me really nervous, because it's going to make worst-case timing very hard to reproduce in testing. (In a way, this has been the case since the introduction of interrupts in the 1960s, but I think it makes the problem much worse.)

If multithreaded or massively multicore processors were a viable alternative, you could get deterministic timings without sacrificing throughput. You could even do away with interrupts. The GreenArrays chip doesn't have interrupts at all; instead, its cores go into a low-power shutdown state whenever they're waiting on I/O.

But that's all pretty speculative.

</comment></comment></comment></comment></comment></comment></comment><comment><USER17> What he's advocating sounds a lot like how things work in the iOS world, in my experience.

<comment><USER18> And thus the insanely smooth user experience on iOS. As an Android developer, this is _the one thing_ I feel makes it difficult to have a polished user experience on Android compared to iOS.

If you think long and hard about each place you call 'new' in java Android apps, it is possible to get a smooth interface. However, the language doesn't encourage it by default like on iOS and you have to put time into it you usually don't have.

For users, milliseconds of jitters and blockiness everywhere is a huge turn off. It feels like the device is struggling to handle simple tasks and it destroys the belief in the UI metaphor of physical objects that have inertia and flow, stretch and bounce when you touch and flick them.

IMO, because it makes such a huge difference to users, UI programming should always happen in a high performance language and environment. One way to attain this performance is to eschew garbage collection. This is also a problem in web browsers where the UI is often written in javascript.

At the very least those who make programing environments, languages or GCs used for building user interfaces should optimize how their environments promote good use of local hardware cache and acceleration. There is a reason why UI rendering often relies on video hardware that is not totally unlike a desktop high performance computer.

<comment><USER19> _And thus the insanely smooth user experience on iOS. As an Android developer, this is _the one thing_ I feel makes it difficult to have a polished user experience on Android compared to iOS._

Yet for WP7 its also silky smooth. The main issue on WP7 for user apps isn't GC at all, but rather the network (creating long lists of images that you're getting from a web service). Once people learned some techniques for dealing with that on the device the experience for 3rd party apps was just as silky as iOS apps -- yet a full generational GC.

The GC is an excuse (unless its not well written), not the reason.

</comment></comment></comment><comment><USER20> I think this is another case of everybody thinks about garbage collection the wrong way: [http://blogs.msdn.com/b/oldnewthing/archive/2010/08/09/10047...](http://blogs.msdn.com/b/oldnewthing/archive/2010/08/09/10047586.aspx)

From the article: "Garbage collection is simulating a computer with an infinite amount of memory. The rest is mechanism."

Whether or not it's reference counting or generational, the goal is still to simulate infinite memory. That way, you can focus on the high-level problems instead of the technical memory-related details. So it's not necessarily a bad mindset to have.

</comment><comment><USER21> Might be worth mentioning Tcl in this context, as it uses reference counting for the GC [1].

It also doesn't allow circular data structures, which are quit hard to implement if all you have are strings anyway.

[1]: <http://wiki.tcl.tk/3096>

<comment><USER22> Perl also uses reference counting, and cyclical data structures cause memory leaks unless you explicitly decrease the reference count with the weaken function from Scalar::Util.

<comment><USER23> And Python. AFAIK, there are no plans to fix it at this point. Also Python is notorious for allocating lots of small objects.

<comment><USER24> Python has a mark and sweep garbage collector(since 2.0) to catch that which reference counting misses. You can disable it if you know you don't make any cyclical objects.

</comment></comment></comment></comment><comment><USER25> [2002]

Though his argument about cache does still hold.

<comment><USER26> I think his opinion might not have changed. In his latest "C++ sucks" rant in that "why is git written in C" thread he points out not having GC as being one of the detriments of C++.

<comment><USER27> For the complexity it adds not having GC _is_ a detriment of C++. The language makes reasoning about allocation, object ownership, etc, much harder. It does this in the course of providing features intended to help you structure and manage larger pieces of code, and thus accidentally works to defeat that purpose.

I don't think Linus ever intended to declare GC as evil or wrong. He was calling it out as a very poor choice that people persist in making for certain domains.

</comment></comment></comment><comment><USER28> I like him mentioning the programmer's mindset associated with GC being a big danger. Some people consider GC a magic bullet and refuse to think about what's happening under the hood. I do not consider that a good habit.

<comment><USER29> It seems to be far easier (i.e., possible) to go from a manual-memory- management style of development to an automatic one than the other way around. I've known plenty of Java-CS-degree programmers who just never could get the hang of writing C/C++ code without leaking stuff (and not just memory).

<comment><USER30> This is a key point that I think lots of GC proponents gloss over. Memory is not the only resource that needs to be managed. Open file handles, sockets, user sessions, whatever... they all need to be managed in much the same way as memory.

</comment></comment></comment><comment><USER31> When I read this, I immediately thought about std/boost::shared_ptr. This is a bit ironic since Linus hates C++ so much.

shared_ptr is a really nice thing in C++. (For those who don't know: It is a ref-counting pointer with automatic freeing.) And its behavior is very deterministic. In many cases in complex C++ applications, you want to use that.

<comment><USER30> Or as we like to call it, std::shared_ptr

</comment></comment><comment><USER32> I like the way the D language approached this. It's garbage collected but it also has a "delete" function/operator. That way you can use garbage collection if you'd like, or you can manually free memory when you think it's worth it.

That seems like a reasonable compromise and I'm surprised that more languages don't do it.

</comment><comment><USER33> I'm very suspicious of anyone (even Linus) claiming that gcc is slow because of its memory management. The codebase is crufty and convoluted--- it's probably slow for a thousand different reasons. If you refactored into a clean design and rewrote the beast in OCaml (or any other language with a snappy generational collector), you'd probably get a large performance boost.

<comment><USER34> I think your argument consists of "gcc is slow because I don't understand the code layout".

One of the problems affecting the C frontend and backend is poor cache locality due to pointer chasing in their data structures, and they currently do switch between GC memory and manually allocated zones (obstacks) to improve this.

</comment></comment><comment><USER35> This is like arguing assembly is better than high level languages because it's faster with explicit control. The thing is 99% of the time it doesn't matter.

In most cases, GC-based programs have good enough performance to get the job done. For the 1% case, sure use the C/C++/Assembly to have the explicit control and performance. Doing things in non-GC systems because of potential caching problem sounds like a case of premature optimization.

<comment><USER34> I really like it when people reply "usually this doesn't matter" to a discussion in a project where it _does_ matter.

<comment><USER35> I got the impression that Linus was discussing GC in general usage in the long post, not specific to the GCC compiler. He even brought up the copy_on_write example, which was a kernel or file system usage.

If the goal is to speed up GCC, there are a long list of things to do before you have to worry about L1/L2 cache miss. Header file processing (or re- processing) is one of the biggest time sinks during compilation.

<comment><USER34> cpp avoids reprocessing:

<http://gcc.gnu.org/onlinedocs/cpp/Once_002dOnly-Headers.html>

Processing header files in the first place is certainly a problem affecting C, but I believe optimizations take more time. Parsing is a much larger problem for C++.

<comment><USER35> I meant reprocessing the same set of header files for every single cpp file including them. Precompiled headers suppose to speed it up. But they still need to be read in and re-created in memory for each cpp file. Why not just compile all the cpp files in one process rather than spawning off a compiler process for every file? That can ensure reusing all the header files processed and are still in memory.

My point is: run the profiler, see what are the bottlenecks, and pick those areas for optimization. Rather than speculating that L1/L2 cache misses are causing the major delay. If they ran the profiler and L1/L2 cache misses are really the problem, then I have nothing else to say.

<comment><USER34> > But they still need to be read in and re-created in memory for each cpp > file.

This is just mmap for Clang. For GCC it... isn't. The other one you mentioned is called a compile server and nobody seems to have cared enough to implement it.

> If they ran the profiler and L1/L2 cache misses are really the problem, then > I have nothing else to say.

<http://gcc.gnu.org/ml/gcc/2011-04/msg00315.html>

<comment><USER35> Compile server, interesting concept. If no one cares to implement it, that means performance is not a high value item for people to improve upon.

That's an interesting problem in doing a lot of lookup from main memory since the data structures are too big to fit in L1/L2. But that usage is not allocating a lot of short lived objects and freeing them, and reusing the freed memory right the way for next allocations. That's what Linus arguing for to reused the L1/L2 for the short lived objects, and thus GC is inappropriate. I would imagine compilers typically allocate objects that have long lifetime, such as declarations that have scope through the whole compile cycle. Also if memory allocation/deallocation is really a performance problem, then don't deallocate, just reuse the buffers. Reusing the same set of buffers would make sure they are hot in L1/L2.

Anyway it has been an interesting discussion.

</comment></comment></comment></comment></comment></comment></comment><comment><USER36> Didn't Linus forget

        newnode->count = 1;

<comment><USER37> Maybe it's done by the _copy_alloc_ function.

</comment></comment><comment><USER38> Here are a couple of reasons why I think it's not so clear cut:

1\. If garbage collection was that damaging to the cache, Haskell wouldn't be nearly as fast as C. 2\. Copy-on-write data structures are nice because the immutability allows for concurrent access without locking.

Granted, this was from 2002 and Linus may no longer feel so strongly about the topic.

<comment><USER39> Show me a memory-intensive kernel in which Haskell runs close to the performance model. Sparse and dense matrix kernels would be a good place to start. Our C code for sparse matrix-vector products and sparse triangular solves gets better than 90% of STREAM bandwidth (based on an assumption of optimal cache reuse, STREAM is about 85% of hardware peak).

Dense matrix kernels should get better than 90% of FPU peak. Unlike sparse kernels, dense kernels are no longer bandwidth limited, but cache reuse in both L1 and L2, as well as friendly TLB behavior is important to good performance.

It would be interesting to see any Haskell implementations that are competitive. I suspect that the very first thing you will do when trying to get performance is to ditch the functional paradigm and start writing code in an assembly-level monad.

<comment><USER40> > It would be interesting to see any Haskell implementations that are > competitive. I suspect that the very first thing you will do when trying to > get performance is to ditch the functional paradigm and start writing code > in an assembly-level monad.

Or teach the compiler about the algebra of arrays and matrices, so it can do the things to the code, that we'd write by hand.

E.g.

* [http://www.cse.unsw.edu.au/~benl/papers/stencil/stencil-icfp...](http://www.cse.unsw.edu.au/~benl/papers/stencil/stencil-icfp2011-sub.pdf)

* [http://www.cse.unsw.edu.au/~benl/papers/repa/repa-icfp2010.p...](http://www.cse.unsw.edu.au/~benl/papers/repa/repa-icfp2010.pdf)

* <http://www.cse.unsw.edu.au/~dons/papers/stream-fusion.pdf>

* <http://www.cse.unsw.edu.au/~chak/papers/acc-cuda.pdf>

In all these cases arrays codes are written in a function style, accompanied with special purpose optimizations and/or code generators (in the case of GPU code), layered over an imperative arrays primitive layer, using a memory effects monad.

<comment><USER39> This is a worthwhile research topic, but it doesn't really answer my question. From the first paper you cite:

 _The single threaded Handwritten C version is about 45% faster than our best Haskell result, which is achieved with 3 threads._

Meanwhile, there is no performance model so we don't know how good the C version is. The paper doesn't even report a simple fraction of FPU or bandwidth peak. It is not using SSE instructions so it cannot possibly be better than 50% of FPU peak (the limit is actually lower because this kernel is/should be bandwidth limited). As for parallelism, I'll quote Bill Gropp [1]

 _The easiest way to make software scalable is to make it sequentially inefficient._

[1] [http://books.google.com/books?id=2Da5OcnjPSgC&lpg=PA21&#...</a>

<comment><USER40> Oh, I'm certainly not arguing that you're going to beat hand tuned straightline code. I'm just pointing out that dropping into assembly isn't the only possibly path.

<comment><USER39> If you're not within 10% for these kernels, chances are that memory is being used differently. This gets to a further matter which I think is perhaps the greatest failure of current multi/many-core programming paradigms: assuming a flat memory model. Efficient parallel computation has much less to do with computation than with data movement. Recent and future architectures have deeply hierarchical memory systems so any paradigm that does not expose the location of physical pages (within some appropriate abstraction) will have a hard time delivering consistent, understandable performance. Performance should not vary an order of magnitude based on whether memory was faulted (allocation is irrelevant) using a batch of threads with different affinity than those that access it later. But this is the current state of affairs.

I would very much like to see a paradigm where a memory distribution (roughly a high-level representation of the mapping to physical memory) was a first- class concept. Suppose that new memory could be allocated or remapped to have certain compatibility relative to the mapping of another block. Then you could associate tasks with certain coupling between two distributions.

<comment><USER41> > If you're not within 10% for these kernels, chances are that memory is being > used differently

More likely imperfect strictness analysis, etc. Haskell is a pure functional lazy language, after all. Getting within 65% of C's performance on a tight numeric kernel is heroic.

<comment><USER39> Different strictness analysis results in using memory differently. Note that some of Don's references are embedding a DSL that gives a high-level interface to very low-level code (e.g. CUDA) specific to this problem. They should have control over strictness.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER42> Slightly related: He mentions that when the containing structure of a sub structure goes away you can free all the resources. The guys behind Samba 4 developed talloc [1] which is build around that idea.

[1] <http://talloc.samba.org/talloc/doc/html/index.html>

<comment><USER43> Arena or pool memory allocation is a very old idea, and has been implemented by many different systems (e.g., Apache/APR, PostgreSQL, lcc).

</comment></comment><comment><USER44> > _In contrast, in a GC system where you do _not_ have access to the explicit > refcounting, you tend to always copy the node, just because you don't know > if the original node might be shared through another tree or not. Even if > sharing ends up not being the most common case. So you do a lot of extra > work, and you end up with even more cache pressure._

It's possible that things were different in 2002, but I don't really think this is the case now. In general, I make the node immutable and never copy it (copying an immutable object makes no sense). In a well-designed code base, mutations happen within the function where the data is created (read: on the stack, where cache locality is a given). Immutability also addresses Linus' concerns with thread-safety. And that's not accounting for concerns which Linus DOESN'T mention, such as increased development speed and correct program behavior.

I'm not the only one saying this. Josh Bloch, for example, recommends immutability and cites cache reasons ([http://www.ibm.com/developerworks/java/library/j-jtp02183/in...](http://www.ibm.com/developerworks/java/library/j-jtp02183/index.html)). And many languages (Haskell, Clojure) are designed heavily around avoiding mutation and sharing nodes within data structures.

This talk of copying nodes to avoid your objects changing out from under you sounds a lot like what I call "writing C in Java". Linus is looking at this from the perspective of, "If they took away explicit memory management from C, this is how I would do it." But OF COURSE if you just bolt a feature like GC into a language that didn't have it before, it won't work well. Effective cache usage in a GCed system requires other language constructs (like immutability).

Now, after all that, I won't make the claim that immutability in a GCed language like Java or C# is faster or even as fast as C with explicit memory management: it would take a lot of profiling code and comparing its functionality to make that claim with any kind of certainty. But it doesn't seem like Linus has done that profiling and comparison either.

</comment><comment><USER45> That was 2002. Here is the state of the art in 2008: <http://cs.anu.edu.au/techreports/2007/TR-CS-07-04.pdf>

Unsurprisngly, things have changed. Many of Linus's complaints were valid, and we've learned how to address them.

</comment><comment><USER46> I find it sad that, to this day, one has to spend so much time worrying about memory management to get decent performance. I've yet to work on a performance oriented project where I didn't need to write at least a couple custom allocators to reduce memory management overhead.

GC systems are no better in this regard. I was told of an interesting hack in a Java program that implemented a large cache of objects by serializing them into a large memory block so that the GC saw it as one big object and didn't traverse it. This resulting in dramatically reduced GC pause times (10x+). When needed, objects were deserialized from the array. Disgusting, but effective.

</comment><comment><USER47> So.. Essentially man the F up and live without GC in the parts that are going too slow instead of saying "Oh it's cool, just wait ten years and hardware will be fast enough to run this anyway". Use GC for stuff that needs to be simple and is fast enough anyway, don't bog down code that's too slow with it.

</comment><comment><USER48> Guy who writes kernel code cares about performance, film at 11.

</comment><comment><USER49> I'm quite sure the machine code generated by my compiler isn't nearly as good as it could be if I hand coded it but the efficiency of not writing in machine code far outweighs any potential performance gains.

<comment><USER50> You have a good point that applies in a lot of places, but here you're aiming it at a straw man. Linus advocates reference counting and even suggests building it into the language would be a good idea. That's hardly hand coding anything- it's just a different strategy for GC (which is actually done).

It is getting harder and harder to beat compilers with hand-coded assembly without an enormous amount of effort, though.

</comment></comment><comment><USER51> "All the papers I've seen on it are total jokes."

Couldn't agree more. We were actually laughing in the office when an office mate brought up such a paper many years ago.

"I really think it's the mindset that is the biggest problem."

Linus is a superhero 20+ years working on the supertask of changing people's mindset.

</comment><comment><USER52> Hacker News, another place where 10-year-old emails are submitted as _news_.

<comment><USER53> Maybe the OP considered it news because it is tangentially related to this patent issue to do with automatically expiring data in hash tables.

<comment><USER52> I assumed that's what the comment section is for.</comment></comment></comment>


Introducing Nvest - <AUTHOR> http://www.nvest.me/

<comment><USER2> Ranking people by their recommendation performance is going to be very misleading for most people. There is this natural intuition to look at the top performers and try to learn from them. In reality, the rankings would look almost identical if everyone just picked everything randomly. Mutual funds and hedge funds exploit this all the time. They start lots of funds that all invest a little differently. They cull the losers and keep the ones that happened to do well. Then they sell prospective investors on their past performance of one particular fund when in reality they didn't need anything more than random chance and multiple tries to get it.

<comment><USER3> Thanks, this was my immediate thought. If Bogle's thesis is correct (which is perhaps equivalent to the efficient market hypothesis), then there should not be anything to be gained by looking at these folks' stock picks in general.

Retrospectively, of course, some of their picks should look like pure gold.

</comment></comment><comment><USER4> I'm creating 2 ^ N fake accounts in order to ensure that I have at least one account with N perfect recommendations. Then pump and dump, baby.

<comment><AUTHOR> We do plan to implement features, such as validating phone numbers, to prevent that.

<comment><USER5> Phone numbers cost $1 to bypass this.

<comment><USER6> Notice that he wrote "features". That's plural, meaning more than one. And then notice that he wrote "such as validating phone numbers". The "such as" part indicates that phone number validation is just one example among several. I'm sure he's quite well aware that phone numbers alone are insufficient. That's why they would likely be combined with other approaches.

<comment><USER5> I'm uncertain why pointing out the mentioned feature is easily bypassed is irrelevant?

It isn't like I was attacking him on it, just pointing out that feature is effectively ineffective except against truly mass bot type stuff.

</comment></comment></comment></comment></comment><comment><USER7> Curious to see how this will be different from Marketocracy [http://en.wikipedia.org/wiki/Marketocracy](http://en.wikipedia.org/wiki/Marketocracy) which has been crowdsourcing public's opinion on stocks, then highlighting the best stock pickers, and then finally building a mutual fund based on the top stock pickers' recommendation.

Long-term Marketocracy funds are under-performing broad index funds FWIW.

</comment><comment><USER8> I had an Econ professor who insisted individual stock picking is a fool's errand, and he had some pretty compelling evidence to back it up. If you have a thousand users picking stocks randomly, some will by chance do well. I wouldn't be comfortable putting money behind the lead users who are likely victors by luck. But then again, its very possible I'm missing something.

<comment><USER9> > I had an Econ professor who insisted individual stock picking is a fool's > errand, and he had some pretty compelling evidence to back it up.

What does your Prof say about Warren Buffett.

<comment><USER10> Presumably this, from the comment you were replying to:

> some will by chance do well.

Buffet's performance _could_ be due to being skilled, or the reason we're talking about Buffet instead of someone else _could_ just be survivor bias.

<comment><USER9> You should read this then.

[http://www4.gsb.columbia.edu/null?&exclusive=filemgr.downloa...](http://www4.gsb.columbia.edu/null?&exclusive=filemgr.download&file_id=522)

</comment></comment></comment></comment><comment><USER11> Buy/sells seem to be only time stamped to a day. Surely you need greater accuracy than that, e.g. the exact second? Otherwise, if I buy a stock on a day where it rises 10%, what price do I get?

Do you take dividends into account? If not, why not?

How do you rank people who make different numbers of picks? A naive method would be to add up all the returns, but this would then favour people who make more stock picks. For example, if I recommend two 'buys' that both give a 10% return, have I gained 20% in total or 10%? (As I would have had to split my bank to invest in both at once)

<comment><AUTHOR> We do take dividends and splits into account. Currently, our approach is compounded ROI.

</comment></comment><comment><USER12> congrats on launching, yet another flashy site with an unoriginal idea. been done before (and better) elsewhere, yet you failed to tackle anything that your predecessors have failed at. Investing is not just about return; the other side of the coin is risk, and you fail to mention that anywhere.

investing is more than just a buy or sell. what about position sizing? what about position risk? portfolio risk? portfolio beta? how do you benchmark? what kind of drawdown do you incur? what's your sharpe ratio? why are you not adjusting returns for at least the market, and moreso common factor returns?

rank(total_return) != investing success

Your "metrics" should be educational and make people more aware of the financial decisions they are making. By boiling it down to buy/sell recommendations, you make investing into gambling with a 50% chance of being right.

your "transparent" ranking algorithm is not disclosed anywhere - do you have any documentation that your algorithm does more than just show who made the most "money" historically? (past performance is not indicative of future performance!) are your rankings stable? how do you identify persistence?

<comment><USER13> On the landing page, they have shown how they calculate the ROI. Also, the idea of acting on recommendation is to seek alpha rather than beta.

<comment><USER12> calculating ROI= (sell_price / buy_price -1 ) *100 does nothing to account for beta

</comment></comment></comment><comment><USER14> Can I track consistently worst stock pickers too?

Then I can fade their bets and become the top :)

<comment><USER15> Hmmm... that would entail you going short when they go long. However, the potential payoffs from going short are asymmetric, with theoretical unlimited downside risk.

How would you deal with that, or would you try to execute through options?

<comment><USER16> You could only trade when they go short.

</comment></comment></comment><comment><USER17> Good luck with it guys. There was a site long ago called clearstation which was bought by Etrade and killed. It offered similar features (charting, profiles, following, tracking, discussion, etc.), they built a great community of traders which was educational and enjoyable to participate in. It's hard to build something good. Keep pushing and good luck.

</comment><comment><USER18> Well done on the website. Navigation is smooth, and the layout is nice. I'm interested to see how this social network for stocks does once you get more users.

</comment><comment><USER19> Are there really enough other places besides Seeking Alpha, Motley Fool's CAPS and StockTwits that publish people's recommendations in such volume that the number of recommendations would be large enough to be valuable outside of these already large established communities?

Or is this whole site's effort merely a feature that StockTwits and the other sites may add later on?

<comment><USER13> Just browse through the Motley Fool website, there are similarities for sure. Then I came across this, [http://caps.fool.com/player/bbmaven.aspx](http://caps.fool.com/player/bbmaven.aspx). This person has a rating of 100, and for a period there, each of his recommendations have consistently made over 500%. I don't know how it is ranked, and I don't think it is correct either.

<comment><USER20> But it definitely felt weird on how they score each recommendations.

</comment></comment></comment><comment><USER21> Reminds me of SocialPicks =)

<comment><AUTHOR> Interesting site!

</comment></comment><comment><USER22> On etoro.com you can even copy the transaction of others with one click. Can you do the same on Nvest or it just provides information?

<comment><AUTHOR> We are currently focused on providing information and stock market. Etoro is mostly working on Foreign Exchange.

</comment></comment><comment><USER23> You don't adjust the returns to risk? Why?

You should have the basic sharpe and sortino ratio at least.

<comment><AUTHOR> I mean there are many mathematical model to calculate risk. But, how do you objectively evaluate risk? We can definitely include multiple different models on the site.

<comment><USER23> > how do you objectively evaluate risk?

You should know this, you are advertising a trading performance evaluation site.

</comment></comment></comment><comment><USER24> I have a hyphenated first name, and was told it was invalid. Replaced the hyphen with a space, was again told my first name was invalid.

Maybe worth looking into your broken name validation.

<comment><AUTHOR> Thanks for the feedback! We fixed the issue. You can now use hyphen or space in your name. Please try it again at www.nvest.me. If there's any other issue, please let me know! Thanks.

</comment></comment><comment><USER15> Will you pull existing recommendations from StockTwits and Seeking Alpha? Or will stock-pickers have to sign up on Nvest before you will track their recommendations?

<comment><AUTHOR> Currently, they have to sign up before they can get tracked. There are challenges to track non-structured recommendations from other platforms. If you have suggestions, we would love to hear about them!

<comment><USER25> We have a system in place for quantifying quotes at [http://backrecord.com](http://backrecord.com) . On the system that is live, all data has been entered by hand. The task is difficult enough that I've found even educated people who know about finance screw up the data entry more than I would like. So we have a sophisticated verification system in place to try and deal with that. We have also experimented with NLP algorithms with some success. If the data extraction is tailored to a particular source, it is quite doable in some cases.

</comment></comment></comment><comment><USER26> Overall a fan and signed up. Some feedback: dated icon and layout has too much of a bootstrap feel. Also, single page application for more responsive UX.

<comment><AUTHOR> Thanks for the feedback!

</comment></comment><comment><USER9> How are you going to monetize this?

<comment><AUTHOR> There are actually many ways! If you are really that interested, ping me at email@example.com!

<comment><USER27> I'm curious too. Will send you an email.</comment></comment></comment>


Build a QR code scanning app with 26 lines of JSON - <AUTHOR> https://medium.com/@gliechtenstein/build-a-qrcode-barcode-scanning-app-with-26-lines-of-json-b83453d39197 <comment><USER2> If this article impressed you check out Shape Detection API that can scan barcodes, QR codes etc. in less than 26 lines and works in Chrome for Android without any external apps: [https://wicg.github.io/shape-detection- api/#barcode-detectio...](https://wicg.github.io/shape-detection-api/#barcode- detection)</comment>


Python vs. C/C++ in embedded systems - <AUTHOR> https://opensource.com/life/16/8/python-vs-cc-embedded-systems <comment><USER2> The argument that new graduates will know Python and have an easier time with embedded systems never sits well with me. If they graduated in something to do with embedded systems then they will know C. If they have a general programming background then they will need some training anyway, as embedded systems often require a different mindset geared more towards low-level programming. So they might as well learn C while they're at it.

I think the popularity of Arduino with complete beginners shows that the barrier of entry is rolling the bootstrapping code and getting tools set up, not the language itself.

</comment><comment><USER3> Embedded systems has begun changing in a way that makes much of this discussion (about Python vs. C++) moot. There are small devices with a ton of compute power that run Linux quite easily, i.e. Raspberry Pi. However, devices are also getting much smaller and consuming less power, i.e. chipsets for smart watches.

Saying all embedded will get so fast that you can always use Python ignores the side that is focused on smaller footprint and power consumption. Saying that embedded is only hard-core C or C++ stuff that must be compiled is ignoring the Arduino/Pi world where devices that used to be clearly embedded are now powerful but still very small.

However, in either case, we do still regularly deal with a lot of issues such as constrained resources, real-time needs, etc. Grabbing a random engineer who knows Python and saying they're going to be good at that is silly. In many, many cases you'll still need to learn how the system truly works top to bottom to be effective.

</comment><comment><USER4> Python being or becoming the most popular _introductory_ language for CS is irrelevant to understanding what _graduates_ know. There's 4 years between their introductory course and their graduation.

A good CS program will introduce CS students to several (hopefully many) languages. Some form of assembly, imperative languages like C, something like C++/Java/C#, hopefully a "purer" OO language like Smalltalk, functional languages like the ML-family, and others. Ideally with a properly chosen language (or a couple languages) in each of the first series of courses, and leaving it up to the students after that for their 3xx and 4xx courses.

And any CS graduate who can't pick up a new language in short order has been cheated out of a good education by their school.

</comment><comment><USER5> in embedded systems? If he is talking about using Python in microcontrollers, he does not know what is embedded system.

<comment><USER6> Does embedded mean micro-controllers only? I've worked on i7 boxes with 16GB of RAM as "embedded systems". Various customers bought them as such. I guess we've been fooling ourselves and our customers for 10+ years.

<comment><USER7> Embedded systems mostly means that the OEM delivers a complete device (hardware and software) where the endcustomer doesn't install anything else. These systems can contain anything from 8bit microcontrollers to i7 processors.

But of course, when many people talk about embedded systems (especially in the context of development) they mean the more constrained devices (microcontrollers without OS or with realtime OS, ...). That's because the others are more PC-like and therefore don't have these special requirements during (software) development.

<comment><USER8> > That's because the others are more PC-like and therefore don't have these > special requirements during (software) development.

Requirements are based on the task, not the hardware. I have written firm real-time software for multi-processor, multi-node Xeon and POWER7 systems.

<comment><USER9> Just out of interest - what were you doing?

<comment><USER8> An airborne radar signal processor. We were using telecom-ruggedized IBM blades to run a large-scale (for an airplane) clustered signal processing application. The processing was divided spatially, but needed to be implemented as a grid because the workers had to move in lockstep through the stages of the pipeline.

</comment></comment></comment></comment></comment></comment><comment><USER10> Python is already incredibly popular when it comes to testing embedded systems, and also incredibly popular when it comes to prototyping algorithms and doing data analysis.

From my perspective, C and Python provide a nice complement to one another and whilst I wouldn't necessarily put Python onto a very constrained embedded target, I'd certainly use it for everything else - simulators, build systems, unit tests, requirements tests, nonfunctional KPI testing, end-of-line production testing, calibration, documentation generation, configuration file generation and all that jazz.

</comment><comment><USER11> How about distinguishing between arduino-level embedded systems and raspberry- pi-level? In first case python is fine, you have full-featured OS anyway already. in second case python doesn't fit at all. what's the question then?

Also, for arduino-level systems i wish there would exist (and in active use) better language then C/C++ something in Rust/Nim/mruby/Crystal-direction. Low overhead and better syntax

<comment><USER12> > In first case python is fine...

I think you meant second case (RPi), just switched up your wording.

</comment></comment><comment><USER13> > When it comes to speed, however, runtime speed isn't the only aspect of > development to consider—you also have to consider development speed.

It is not clear what sub-domain of the embedded-systems world this article targets. I read once somewhere that controlling equipment for nuclear stations is also embedded development. In general though, first and foremost, you will be considering the BOM cost -- how to reduce it, and how your software choices will impact it.

Several strategies are possible: in the small-uC world, people start by developing on higher-end models, then optimise the size and speed as the product ships, to shoehorn the sw into a smaller, less expensive models. This is only possible if the cost of validation is not prohibitive (and if it is at all possible to re-validate the product again -- think about any possible re- certifications to do if the hw changes).

If such re-validation is too costly or impossible, one will be cost-optimising the platform right from the start, and in general, cost of development -- an important factor (especially for those who has failed a product at least once ;-)) -- will come only in second to that.

</comment><comment><USER12> I think an important point in the context of Python (and other languages) vs. C/C++ is the proliferation of cheap hardware capable of running Linux. The relatively new phenomenon of a $10 Linux device makes it an attractive option in many situations. The cost gap between a traditional microcontroller (no Linux) and a linux device is closing.

The Linux device is compelling when speed (and ease) of development is important, scale is low, or the market is insensitive to pricing. Not to mention the added bonus of more processing power. On the other hand a traditional microcontroller is still compelling where volumes are high or there are strict real-time concerns.

As an embedded software engineer, I'm watching closely. Personally I'm reaching up to higher languages like Python to make myself more attractive in an industry that I see moving toward more Linux devices.

<comment><USER14> What do you think about MicroPython?

<comment><USER15> I am a total MicroPython fan boy. I've done a lot of embedded C-on-bare-metal development and related electronics. For most non-embedded work, I use Python and am a huge fan of the language, so having Python on an ARM Cortex gets me very excited. MicroPython is absolutely great for getting a complex embedded project up and running quickly. Execution performance, of course, is nowhere near C. But, since a lot of performance critical I/O handling is already done as a C extension (import machine), and it is just as easy to write a MicroPython C extension as it is to write a CPython C extension, you can always move the performance critical parts to C as needed. Overall it is a huge win in development time. MicroPython does require a fairly biggish ARM Cortex M3, though.

<comment><USER16> > MicroPython does require a fairly biggish ARM Cortex M3, though.

What do you mean? I run it on an ESP8266 just fine, the tooling isn't great (it launches a REPL and takes up your serial port with no way to stop that), but other than that it's fantastic.

<comment><USER15> Yes, but the ESP8266 is a bit of a squeeze. It's a more comfortable fit on larger processors.

As to the serial port/repl issue, can't you build your own image to do something else that you like better? Micropython is pretty easy to build, in general.

<comment><USER16> I imagine I could, but I'm very bad with C :(

The REPL is _fantastic_ when you want to prototype stuff, but it's not great when you want to actually deploy things. I'm sure there's going to be some way to avoid launching it in the future, though, such as having a main.py file that has a `repl.run()` you can take out when deploying your own code.

<comment><USER15> The code for Micropython is very well structured. The toolchain is pretty easy to set up, just apt-get and go. The configuration things like I/O pin assignments and such are all on pretty simple definition files. I'd be very surprised if the repl loop takes more than flipping a #define to turn off. No C wizardry needed.

<comment><USER16> Hmm, I'll have a look, but currently you need the repl to be able to write files (otherwise I'd have to include my files in the firmware and copy the entire thing every time).

That's not really so bad, as it's what you do for the C++ version, but it would be nice if there were a way to update the code somehow. Maybe I'll write some code to fetch a file from an HTTP server and unpack it, though.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER17> Python is great for simulating, processing data, providing an interface to automation control, but I'd still use C++ for anything time critical. With more recent versions of the standard and Boost, you can be quite productive with C++ without giving up much in the way of runtime performance.

<comment><USER16> I don't know C++, so take this with a grain of salt, but I'd rather use Rust for those things right now. The problem with the embedded landscape right now (I mean really embedded, not MCUs that run Linux) is that tooling around using unrelated libraries isn't very good.

I use PlatformIO for managing dependencies, but generic libraries that aren't exclusive to embedded programming aren't in the repositories. In general, if you want to add a library, you unzip it into a directory and pretty much never update.

I find development with C/C++ _much_ more painful than with Python, when most of the time I just want the thing to work, not to spend two hours writing boilerplate.

<comment><USER9> Erm, Rust-as-designed may or may not be suited for embedded, but Rust-as-it- is-now has some nasty limitations - not the least of which is the lack of support for anything that is not ARM.

<comment><USER18>
      > not the least of which is the lack of support for anything that is not ARM.

This might be true with regards to embedded architectures, but isn't in general; MIPS and PowerPC are in tree, and we can fundamentally support anything LLVM can, there's just the initial work to get it going.

Which platforms are most important to you?

<comment><USER16> It's too bad that nobody is replying to you. Personally, I would be over the moon if I could develop for the ESP8266 in Rust, but that might be a tall order, since it's a very small chip.

<comment><USER18> Funny enough, when researching this, [https://news.ycombinator.com/item?id=9573390](https://news.ycombinator.com/item?id=9573390)

It seems like a lot of people are interested in this, but there isn't an LLVM backend yet. There is someone working on a Rust -> C transpiler, so if that matures enough...

</comment></comment></comment></comment></comment></comment><comment><USER19> I think 'Python vs C ...' and 'Python vs C++ ...' are different questions. Much like 'C vs C++ in embedded systems' is its own topic.</comment>


Ask HN: Interested in buying my site? - <AUTHOR>

I am posting to see if there's any interest in buying my first commercial project, Certician (https://www.certician.com/).
Certician is an SSL monitoring service that checks customers' SSL certificates for upcoming expirations or misconfigurations.
The codebase has CheddarGetter (recurring billing) and Twilio (SMS) integration. It's written in Django (a Python framework).
I'm thinking about selling it because I don't have the time, money or passion to grow it. I also believe that it's a truly useful service and that someone more motivated could do well with it.
In addition to it being a useful service, I believe that I've come up with a moderately good looking site and a good brand (see the logo: SSL + Physician = Certician).
I have very little traffic and only one paying customer. This site is not something you'd want to acquire in order to instantly gain an immediate source of revenue, it's a site you'd acquire because you see potential and have the passion to grow it.
I'm also not willing to post this on Flippa or the like because I don't want the site or the domain to go to someone distrustful. As a long-term member of HN, I'm confident that a fellow HN user will be a better steward than a random buyer.
If you're at all interested, please contact me via the site: https://www.certician.com/contact/
Thanks for your time. <comment><AUTHOR> Clickable: <https://www.certician.com/> <https://www.certician.com/contact/>

</comment><comment><USER2> Hmm.. how about $25 for it? </DigitalPoint troll>

<comment><AUTHOR> Can you do $30? ;-)

<comment><USER2> No.</comment></comment></comment>


Ask HN: How do you deal with customer support requests? - <AUTHOR>

We have a location-base iPhone game that has been growing rapidly since we made it free. However, with the growth comes an increase in support emails. Currently it is just two founders (one technical, one business). We both try to share the load, but it is difficult to not step on each other's toes.<p>Assuming that you had to have incoming requests come in to an email address, how do you handle them? <comment><USER2> Are you talking about keeping the emails sorted out, and remembering who answered what? For that I use Email Center Pro (<http://www.emailcenterpro.com>). If you have a catch-all email address like email@example.com, you set it up to be checked by Email Center Pro, and you can assign incoming emails to specific users, and track followup. It shows threaded conversations with comments alongside, and you can save templates for common responses.

</comment><comment><USER3> Don't offer email support to non-paying customers. Set up a forum for free users to help themselves. Jump in when you can, but don't spend all your time on it.

</comment><comment><USER4> Assuming you are actually keeping up with the support requests, and you're just wanting to avoid both people replying to the same email, any random division will do - for example, one answers emails that come in midnight to noon, and the other noon to midnight. Don't over-engineer this - since only one of you is technical, there's no chance both of you will be fixing the same problem.

But definitely what chaosmachine said - you should be looking to set up a forum. If you are lucky enough to attract a "groupie" (you know, the super helpful enthusiastic user that is answering everybody's question), make sure you reward them (free invites, recognition, r0shirt, whatever makes sense).

</comment><comment><USER5> Hire people? If it is growing rapidly yet you can't afford to hire someone to handle such a task, perhaps you need to revisit how to monetize it.

</comment><comment><AUTHOR> Thanks for these suggestions everyone!</comment>


Ask HN: How do I promote my ICO? - <AUTHOR> We(team of 3) have built a really interesting coin which we think we have a really really really cool concept.
Since all of our team are independent tech ninja's and have limit->0 knowledge on marketing especially ICO marketing, we really need some ideas/suggestions how do we can proceed?
PS: We already released our whitepaper and it was loved by almost everyone who read it and we are receiving complimentary emails every day. <comment><USER2> The whitepaper is key but no one reads it. It's just a checkbox that you've written it. Focus on wins with partners, large crypto buyers, and exchanges, and push the good news to the community. Generate HYPE is key [http://www.chynge.net](http://www.chynge.net)

</comment><comment><USER3> I would highly advise not to call yourself "ninjas" if this isn't a scam and is targeted at technical people.

</comment><comment><USER4> Hey, what is the best way to contact you? I may be able to help.</comment>


Be Careful What You Wish for (especially If It Is Hitler) - <AUTHOR> http://blog.dilbert.com/post/156540315831/be-careful-what-you-wish-for-especially-if-it-is <comment><USER2> So what he's saying is, if Trump ends up being like Hitler, it's our fault, for thinking he would end up like Hitler? Because we'd prefer Hitler to having Scott Adams think we're confirmed morons?

I guess I _am_ a confirmed moron, because I used to look up to Scott Adams. What a disappointment he's turned out to be.

<comment><USER3> It was weird enough when Adams was doing his "I don't support him, but trump will win because he's so enchanting" bit.

When he flipped his support _to_ Trump over Hillary's estate tax policy, because "it might one day" apply to him (it wouldn't have applied to him currently, had (Hillary, if she won|Trump) enacted that policy, by a long shot) I just stopped trying to understand his logic.

Edit: clarified about ET not applying to Adams.

<comment><USER4> talk about not wanting to admit your wrong and looking like a moron.

</comment></comment></comment><comment><USER5> Some top class victim blaming right here. He doesn't address the concern that this particular Executive Order victimizes a broad swath of minorities for no justifiable reason other than to please a large section of society. What's more, the hatred amongst that section for the minorities was stoked by the person issuing the order in the first place. That is remarkably similar to how Hitler started out. But no, it's the protesters' fault if the situation turns anarchic.

> the alternative to Trump becoming Hitler is that they have to live out the > rest of their lives as confirmed morons.

No, it isn't. If a candidate makes promises that sound a lot like the ones Hitler made ("all of your problems are because of <minority>. We'll get rid of them and make <country> great again") it's reasonable to think that the candidate might follow through with that. If the candidate later sees the light, or is unable to push that agenda for some reason, then that's excellent. Everyone is happy with that and no one looks like a moron, they're just relieved.

> how excited/happy the Trump critics seem to be

Perhaps people are happy that others share their views, that others are willing to stand up for what they feel is right and they're willing to protest on the streets to make it happen. If people saw that everyone around them reacted with apathy, they'd feel the exact opposite.

Maybe what Scott Adams is saying would be easier to swallow if it didn't come right on the heels of this Executive Order, which implements some of the worst things Trump promised on the campaign trail. The Order even has some classic authoritarian hallmarks - a temporary measure until we can "figure out what is going on". Makes it easier to accept for now, but does anyone imagine that on day 57, the White House will experience an epiphany about this that will "solve" the problem they're talking about? No, this measure will be renewed again and again, similar to how Erdogan in Turkey and Maduro in Venezuela renew their "temporary" emergencies.

Coincidentally, Erdogan, Maduro and Trump all promised to return power "to the people".

<comment><USER6> > He doesn't address the concern that this particular Executive Order > victimizes a broad swath of minorities for no justifiable reason other than > to please a large section of society.

This point was addressed in his prior blog post (same day):

>> [...] Are Trump's temporary immigration plans chaotic? Yes. _Do they hurt innocent people who were minding their own business? Yes, temporarily at least._ Did he scare the pants off of half the country? Yes. Will there be lots of unintended damage from Trump's immigration orders? Yes. No honest person should deny the cost component of the equation. It's ugly. But don't stop with a half-pinion. If you want a full opinion on immigration you have to compare those costs to the potential benefits that include fewer terrorist acts and avoiding Europe's refugee problems. Are people making that comparison? >> >> No. [...]

\- [http://blog.dilbert.com/post/156532225711/the-persuasion- fil...](http://blog.dilbert.com/post/156532225711/the-persuasion-filter-and- immigration)

The first post is much better than its followup.

I appreciate Scott Adams' take because he provides a deeper reason for why the candidate/president does what he does.

<comment><USER3> Of ~780K refugees accepted since 11-9-2001 about a dozen have been arrested/deported for terrorism/related threats/risks.

That's 0.0015%.

Trump is a racist, sexist, self absorbed human shit can. No ifs or buts about it. He proved that himself during the ridiculous primaries and election process.

There is no deeper reason. The man is a clown obsessed with his own reflection in the mirror and how many people love his balloon animals.

</comment></comment></comment><comment><USER7> There is something to this. Collective expectations are a powerful force. If most of us feel that in the 21st century every child deserves a good education, or healthcare, we will act in a certain way when we see a child not getting it.

That having been said, most Americans on the left and right have an expectation that their country has a great tradition and robust institution for human rights. Conservatives emphasize financial freedom. Liberals emphasize social freedom. Both claim to emphasize freedom of speech, etc.

So the difference is that even if Adams' theory is correct and people "wishing for" Hitler thereby "bring him about", they have also "wished for" a Congress and Judicial branch that care enough about the above rights that they would impeach and charge him with high crimes or treason if he ever violated serious rights.

We can apply this logic to existing phenomena. I am a liberal and see Republican opposition to Obamacare largely as hypocritical partisanship. Millions of Republicans are _gleeful_ if Obamacare leads to growing deductibles, bad availability of good insurance plans in some states, and millions dropping coverage because they can't afford it anymore. Sad right? But, they are doing it out of a sense that at the Obamacare mandate is against the principle of Freedom. While that may be misguided, and their opposition to single payer in Healthcare might look silly alongside their acceptance of it in Public Education, nevertheless look at the motivation. Americans across every major party share a respect for values of Human Liberty and Limited Government. This is a good common ground.

I say that, what as should really preserve is the systsm of checks and balances. Hitler by himself no matter how powerful is nothing without centralization of government and a removal of the opposition. What you _should_ worry about is the 2010 REDMAP gerrymandering and the refusal to vote on supreme court justices nominated by Obama. That is actually a dangerous example of a party stealing power permanently from the people by breaking the rules.

Already a judge in NYC pushed back on the ban. And by pushing the GOP to repeal-and-replace Obamacare ASAP, or refusing to do anything negative to Saudis and Russians, Trump is not actually making the Republicans any more comfortable with him.

</comment><comment><USER8> Trump is seen negatively because he can't deescelate any situation. He doubles down on the dumbest, most easily disprovable stuff. His narcisism runs deep so it's easily taken advantage of by folks with nutjob agendas like Bannon and Flynn.

Honestly he's more of a King George III than Hitler. Hitler had much more of an agenda, backed by a competent team, than Trump has. Trump's a 2-bit narcissist that's attracted crazy dead-enders. The threat is a combination of fringe politics, insanity, and incompetence.

<comment><USER2> I agree Trump doesn't have much of an agenda, but I fear Bannon and his ilk do.

<comment><USER4> scott adams talks to breitbart

[http://www.breitbart.com/big- government/2016/08/15/dilberts-...](http://www.breitbart.com/big- government/2016/08/15/dilberts-scott-adams-breitbart-trump-not-trying-win- moment/)

</comment></comment></comment><comment><USER9> I don't entirely agree with him, but I think we need to be careful about confirmation biases.

This situation about a police state may get out of hand, especially if Trump and local government authorities feel like they need to crack down on it.

What's more important (and more effective) will be lobbying directly to members of Congress to oppose Trump's (and Bannon's) directives.

We are already seeing a number of Republican senators condemning Trump's actions. This number needs to grow to have a chance of Congress being a check to Trump's powers. If Americans think Trump is unfit for the presidency and should be impeached, it needs to be done the right way and via legitimate channels.

</comment><comment><USER10> Scott Adams makes a very valid point. Fortunately some of us don't get excited at all. Just disgusted and watchful.

The worldwide solidarity which is building up can even be net positive.

Also once he decides to open his first torture chamber he can be assured that everyone in his family involved or complicit will one day be persecuted as war criminals. The judgement of the righteous people is ultimately inevitable.

</comment><comment><USER11> say what you will about Hitler, at least he killed Hitler!

</comment><comment><USER12> In Soviet Russia wall not keep people out; wall keep YOU in!</comment>


Extend the life of threads with synchronization (C++11) - <AUTHOR> http://stackoverflow.com/q/15252292/3986712 <comment><USER2> My two cents -- just use Cilk Plus: [https://www.cilkplus.org/tutorial-cilk- plus-keywords#spawn_a...](https://www.cilkplus.org/tutorial-cilk-plus- keywords#spawn_and_sync)

Why I like it:

\- easy to learn (3 keywords total: cilk_spawn, cilk_sync, cilk_for)

\- runtime handles thread creation, deciding appropriate number of threads based on hardware

\- provably efficient work-stealing scheduler

\- natively supported in GCC 5, branches available for GCC 4.8/4.9 and Clang

\- comes with a race detector (guaranteed to discover determinacy/data races)

\- trivial to convert your parallel code to serial (#define spawn/sync keywords -> empty string, and cilk_for -> for)</comment>


Go 1.9.2 and Go 1.8.5 are released - <AUTHOR> https://groups.google.com/forum/#!topic/golang-nuts/s8EXcSSJ5cg <comment><USER2> If you'd rather avoid Google Groups, the release summary is available at golang.org:

[https://golang.org/doc/devel/release.html#go1.9.minor](https://golang.org/doc/devel/release.html#go1.9.minor)</comment>