Live data from Hacker News

Comparison of C++17, Go, and Java for a next-generation sequencing tool

bmcbioinformatics.biomedcentral.com

81–90 of 190 posts

Re: Comparison of C++17, Go, and Java for a next-generation sequencing tool

#81

Earlier quoted context omitted.

It was mentioned in the article and was not considered a candidate due to a specific API requirement: > Other mature programming languages with support for reference counting include Objective-C, Swift, and Rust [50]. However, in its algorithm for duplicate marking, elPrep requires an atomic compare-and-swap operation on reference-counted pointers, which does not exist in those languages, but exists in C++17.

Except that this "atomic" operation over shared_ptr's in the C++ standard isn't actually required to be lock free, and is in fact not lock free in common stdlib implementations. So they're not actually gaining anything over, e.g. RwLock >> in Rust.

They are atomic in the sense that it is not possible to observe the intermediate states and they are not data races.

It is extremely hard though to implement them in a lock-free way without a true DCAS (which pretty much no architecture implements). I think all implementations use spinlock pools. I guess transactional hardware could be used.

This is one of the reasons why GC does make it easier to implement some lock free algorithms as you do not have to worry about races during memory deallocation. Without GC, I I guess the next best thing is RCU or harzard pointers, but they are significantly more complex.

From a cursory read I do not see any fancy lock free algorithm in the code though, so I'm not sure why they need atomic operations on shared_ptrs.

Re: Comparison of C++17, Go, and Java for a next-generation sequencing tool

#82
post #69

After quickly glancing the code, I concluded that they wrote C++ like there is no static type. It seems they faithfully ported the very dynamic nature of their existing code to C++ without thinking. Like what is this? https://github.com/ExaScience/elprep-bench/blob/master/cpp/f... auto alns = any_cast >>>(data); So the data is sam_alignment type inside shared_ptr inside deque inside another share_ptr inside god forbi…

The use of 'any' and the ridiculous levels of boxing is bizarre. There is also absolutely no attempt at using std::move; the amount of gratuitous copies and refcount updates is staggering. Having said that, apart from the use of std::any, the code is fairly clean even though obviously is not even remotely written for performance..

It's actually more surprising that the person who can write this otherwise clean and modern C++17 code produce this awful abomination.

The only possible explanation is, he literally port the existing code written in a very dynamic language by hand.

He is not stupid, far from it. It's just he also ported the dynamic part of the code so well.

Re: Comparison of C++17, Go, and Java for a next-generation sequencing tool

#83
post #69

After quickly glancing the code, I concluded that they wrote C++ like there is no static type. It seems they faithfully ported the very dynamic nature of their existing code to C++ without thinking. Like what is this? https://github.com/ExaScience/elprep-bench/blob/master/cpp/f... auto alns = any_cast >>>(data); So the data is sam_alignment type inside shared_ptr inside deque inside another share_ptr inside god forbi…

>the unordered_map is very slow(it's a node based hash map, not suitable for the modern hardware) It is very slow? I wrote my app in FreePascal. I need a hashmap, but FreePascal has no real standard hashmap, so I have been benchmarking Pascal hashmaps for weeks/months. Today I added std::unordered_map for comparison. It will still take a day to run the benchmark, but so far it looks that std::unordered_map is 25% fas…

Depends what you do. If you populate it only once and then you do a bunch of lookups, assuming a low load factor, you'll be paying for a modulo operation and an extra indirection, not great but not terrible either. If you do a lot of inserts and removal or your load factor is high, then the performance is going to be not great.

Re: Comparison of C++17, Go, and Java for a next-generation sequencing tool

#84
post #79

Earlier quoted context omitted.

What's wrong with unordered map?

It's implementation is buckets divided node based hash map. Theoretically, its order is good, but not that efficient in modern hardware where the memory access is heavily cached so the data locality is more important than saving the memory copy or memory size. Using the linked list to save some memory copy doesn't benefit at all and the overhead is far greater than simply copying the contagious large chunk of memory.…

> contagious

normally I wouldn't point out an obvious autocorrect mistake, but this is really season-appropriate (or, better, inappropriate) :).

Re: Comparison of C++17, Go, and Java for a next-generation sequencing tool

#85
It would be interesting to see an output of the compiler flags used in the C++ program that was benchmarked. The build script doesn't set an optimization level so it would default to -O0:

https://github.com/ExaScience/elprep-bench/blob/master/cpp/m...

I am sure they didn't benchmark it like this but it would be interesting to see the flags that /were/ used.

Re: Comparison of C++17, Go, and Java for a next-generation sequencing tool

#86
post #69

After quickly glancing the code, I concluded that they wrote C++ like there is no static type. It seems they faithfully ported the very dynamic nature of their existing code to C++ without thinking. Like what is this? https://github.com/ExaScience/elprep-bench/blob/master/cpp/f... auto alns = any_cast >>>(data); So the data is sam_alignment type inside shared_ptr inside deque inside another share_ptr inside god forbi…

>the unordered_map is very slow(it's a node based hash map, not suitable for the modern hardware) It is very slow? I wrote my app in FreePascal. I need a hashmap, but FreePascal has no real standard hashmap, so I have been benchmarking Pascal hashmaps for weeks/months. Today I added std::unordered_map for comparison. It will still take a day to run the benchmark, but so far it looks that std::unordered_map is 25% fas…

std::unordered_map is supposedly slow because it has fairly stringent iterator invalidation requirements. In my experience, unless you wring the most performance out of your code as you can, it's not a huge issue; it's generally faster than most casual implementations.

Re: Comparison of C++17, Go, and Java for a next-generation sequencing tool

#87
post #35
post #24

Earlier quoted context omitted.

> Common Lisp also lets you use mmap But not without allocating dynamic memory and copying data. > They clearly wanted automatic memory management Most likely because of some misconceptions. > so the C++ implementation is reasonable. How so? > but I suspect the results would have been similar Don't forget the data sets to be filtered, sorted an analyzed are up to 200 GB.

> > Common Lisp also lets you use mmap > But not without allocating dynamic memory and copying data. Sure it does. In SBCL you can force a stack allocation (though rarely does it improve performance), and very short-lived values do not leave registers in any case. > > They clearly wanted automatic memory management > Most likely because of some misconceptions. There are both good and bad reasons to want automatic mem…

> > Don't forget the data sets to be filtered, sorted an analyzed are up to 200 GB.

> Which is going to be rough on any automatic memory management system

You could equally say that it makes the case for actually designing memory allocation strategy (which only C++ really supports) that much more important.

You always see this in Java programs for large data analysis. They pick java because of memory management and the tooling. But it's just SO slow and after optimisation the only thing that stubbornly remains up there in the profiler data is memory and GC. And what do they do?

A global object of the following form:

  class DataStore {
    float theFloatsWeNeed[constHowMany];
    int theIntsWeNeed[anotherConst];
  }
You get the idea. Because this avoids memory allocation in java. And you use the flyweight pattern to pass data around. Or you fake pointer arithmetic in java. You create your own pointers by specifying indexes and you oh the horror use math on those indexes. Even then just checking those indexes actually becomes a significant time sink (and then you disable that, which of course kills memory safety in java, but you won't care).

The truth is you don't want memory management for large amounts of data. You don't want to allocate it, track it or deallocate it at all. You leave it in it's on-disk data format and never serialize/deserialize it at all. You want to mmap it into your program, operate on it and then just close the mmap when you're done. C++ definitely has the best tools for this way of working.

Re: Comparison of C++17, Go, and Java for a next-generation sequencing tool

#88
post #44

Earlier quoted context omitted.

Sorry about the naive question, but if the memory management overhead is worse in Swift, is the hardware it runs on typically better? I'm assuming some of this because I've noticed Android devices tend to require more CPU/memory compared to iOS devices in the same generation.

Apparently the custom processors used in iOS devices are actually some of the fastest out there in that form factor. Designed by apple (I think using ARM instruction set) and made using some of the latest, most advanaced, process nodes by TMSC. If you look at raw benchmarks, they handidly beat the best Qualcom/"android SOC" chips out there. I think this changes very rapidly - given the market segment of high end phon…

> I think this changes very rapidly

Apple has been leading the mobile processor market by quite a bit for the last five years.

Re: Comparison of C++17, Go, and Java for a next-generation sequencing tool

#89
post #69

After quickly glancing the code, I concluded that they wrote C++ like there is no static type. It seems they faithfully ported the very dynamic nature of their existing code to C++ without thinking. Like what is this? https://github.com/ExaScience/elprep-bench/blob/master/cpp/f... auto alns = any_cast >>>(data); So the data is sam_alignment type inside shared_ptr inside deque inside another share_ptr inside god forbi…

We should break ABI on unordered map just to stop embarrassing ourselves in public and in front of new users.

why not just define std::dict or something like that that is better?

Re: Comparison of C++17, Go, and Java for a next-generation sequencing tool

#90
post #44

Earlier quoted context omitted.

True. C# and Java constantly beat Swift on speed.

Sorry about the naive question, but if the memory management overhead is worse in Swift, is the hardware it runs on typically better? I'm assuming some of this because I've noticed Android devices tend to require more CPU/memory compared to iOS devices in the same generation.

Swift is currently missing some optimizations that would allow for better knowledge of object lifetimes and potential elision of refcount updates.
Post reply on HN