8 ms·
I think C++ is just fine. Memory management is not that hard anymore using smart pointers. I prefer that to java at any time of the night or day. Such an ugly v
by cjfd 5y ago
I think C++ is just fine. Memory management is not that hard anymore using smart pointers. I prefer that to java at any time of the night or day. Such an ugly verbose language. The buzz word laden stuff is actually quite bad. I have seen what could be rather simple systems be very unreliable and slow because of the many microservices all in their own container. Then if one is sensible enough to avoid that there is another pitfall. The cool kids like thread pools and having everything asynchronous. So a computation migrates between different threads many times between initiation and completion. I say instead: keep as much as possible single threaded and only offload expensive computations to thread(pool)s. That way one also does not need to lock the whole world, which, by the way, is far from free. Also, there are many situations where one can split computations in threads naturally as dictated by the problem one is trying to solve instead of dumping everything in a thread pool without considerations regarding what kind of queue system one implicitly creates. E.g., if one has N input channels and N is not too large one might have N threads for that.
- rightbyte 5y agoSmart pointers has some overhead though, even unique_ptr. I like to use raii to handle normal pointers. For many programs memory leaks can just be handled by exit, too.
- Glamhoth 5y agounique_ptr has zero overhead
- cjfd 5y agoThis appears to be incorrect. I have seen a cppcon talk about that. I think it may have been this one: https://www.youtube.com/watch?v=rHIkrotSwcc https://www.youtube.com/watch?v=rHIkrotSwcc . On the other hand, it is a very, very tiny minority of programmers who have to care about an overhead as low as this. Most of us should not waste one microsecond of our thinking time on this.
- JonChesterfield 5y agoKind of true for unique_ptr as a C++ construct. Sadly if the platform ABI is not ignored there is (usually? might be free on some platforms) overhead relative to a void* when passing one between functions. Also there's the usual code size / compile time hazards of templates.
- berkut 5y agoNot when stepping through code in gdb/lldb in my experience in debug builds: they very often end up stepping in to the -> operator implementation for functions, which then requires me to step in again to get to the actual function call I wanted.
- ncmncm 5y agounique_ptr has zero overhead except when passing or returning by move. But I don't find myself doing that anywhere performance matters. The overhead is not inherent, but is rather a consequence of C ABI choices inherited into C++ calling conventions. It is, though, real, and not easily fixed. E.g., RISC-V's ABI binding peobably suffers from the same overhead, not for any good reason, but just because the RISC-V crowd couldn't spare the attention to fix it.
- cjfd 5y agoThis would seem to be a very micro optimization, though. If you are in a tight loop, sure, but otherwise I would say that smart pointers are a rather low price to pay. And if you are in a tight loop it may be better to try to avoid memory allocations altogether and try to reuse objects instead. In any case the price of smart pointers is orders of magnitude smaller than the price of what passes as 'modern' software development.
- rightbyte 5y agoSure in general, but I would not call it a micro optimization, if you are choosing between shared_ptr and normal ones or unique_ptr.
- charcircuit 5y agosmart pointers is raii for normal pointers
- dan-robertson 5y agoThis feels like Stockholm syndrome to me. 1. I’m amazed that you call Java ugly and verbose but recommend C++. Apart from files not needing to be classes in C++, they feel similarly verbose to me with C++ slightly winning on ugliness. 2. I basically don’t believe that memory management is not hard. The reason is that plenty of programs written in ‘modern’ or ‘safe’ C++ in the style you recommend continue to have plenty of memory unsafety based bugs, crashes, and vulnerabilities. P.S. Most async systems try to keep things on a single thread. Their main purpose is allowing a higher level of parallelism than can be economically achieved with threads, and normal good async style is to have most things non-async and therefore single-threaded. On Linux, a lot of the purpose of the thread pool is doing system calls that are blocking. io_uring makes it less necessary but many people use kernels that are too old.
- jcelerier 5y ago> 1. I’m amazed that you call Java ugly and verbose but recommend C++. Apart from files not needing to be classes in C++, they feel similarly verbose to me with C++ slightly winning on ugliness. I've always found java much much more verbose. here's e.g. hello world in javafx: package helloworld; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.StackPane; import javafx.stage.Stage; public class HelloWorld extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("Hello World!"); Button btn = new Button(); btn.setText("Say 'Hello World'"); btn.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { System.out.println("Hello World!"); } }); StackPane root = new StackPane(); root.getChildren().add(btn); primaryStage.setScene(new Scene(root, 300, 250)); primaryStage.show(); } } here's a Qt version: #include <QtWidgets> int main(int argc, char** argv) { QApplication app{argc, argv}; QPushButton button{"Say 'Hello World'"}; button.setWindowTitle("Hi"); QObject::connect(&button, &QPushButton::clicked, [] { puts("Hello world !"); }); button.setMinimumSize({300, 250}); button.show(); return app.exec(); } notice for instance creating an object just with {} ; just that saves me I don't know how many hundreds of keystrokes. Also no need to ever `new` anything, just name the types directly. No need to repeat types à la StackPane root = new StackPane(); C++ would just be StackPane root; or maybe auto root = StackPane{foo, bar}; observer pattern can be much less braindead thanks to the early existence of templates, and let's not even talk about https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html https://docs.oracle.com/javase/8/docs/api/java/util/function... Quoting stackoverflow: https://stackoverflow.com/questions/18400210/java-8-where-is-trifunction-and-kin-in-java-util-function-or-what-is-the-alt > There are ready to use Consumer3..Consumer8, Function3..Function8, Predicate3..Predicate8 in reactor.function package of Reactor Addons library that is bundled with Spring Framework. like, come on... same for Optional which gets some unrelated custom OptionalInt because there was no value type and adds boilerplate for nothing.