6 ms·
I wonder whether Java will get displaced by Swift on the server at some point. Anyone want to place bets? No garbage collection, so no GC performance hiccups.
by abalone 10y ago
I wonder whether Java will get displaced by Swift on the server at some point. Anyone want to place bets?
No garbage collection, so no GC performance hiccups. No explicit threading for easier concurrency.[1] Optionals for protection from null pointer exceptions. These are 3 of the biggest problems in server-side Java programming, I'd say. That's before we even get to the elegance of the syntax.
[1] https://developer.ibm.com/swift/2016/02/22/talking-about-swift-concurrency-on-linux/ https://developer.ibm.com/swift/2016/02/22/talking-about-swi...
- johncolanduoni 10y ago> No garbage collection, so no GC performance hiccups. If your models are naturally highly cyclic, dropping a GC can vary from painful to near impossible. I think a better solution for most server-side code (from both an ease of use and performance standpoint) is to use a hybrid GC/arena approach, centered around tasks. If most of your work and memory churn centers around discrete and relatively short-lived requests, you can allocate all objects whose lifetimes are bounded by the duration of the transaction in a thread-local arena. You can't beat unsynchronized bump-pointer allocation, and you can simply throw the memory away at the end. I've been really disappointed with the lack of innovation in the memory management space. Rust is the only recent language I've seen that did something more significant than choose between GC and reference-counting.
- abalone 10y agoPainful in terms of what?
- johncolanduoni 10y agoJumping through hoops and hoping you put enough weak pointers. Such structures, if they are getting mutated, also tend to take significant performance hits even if you get it right, because of all the synchronized increment/decrementing. Another place where this can really hurt is "reactive" approaches, where cycles are very hard to avoid. Weak delegates (like what WinRT uses for events) can help here, but they raise a number of complications. The biggest is that they compose poorly: if you have an intermediary in your event chain, you need to make sure the subscription is the only place where a reference is being held.
- abalone 10y agoFWIW I will try to summarize the Swift architect's comments on this:[1] a) Declaring weak pointers does take some more reasoning about your object graph. A silver lining is it makes the intention of your code more explicit which helps with maintenance. b) Swift emphasizes value types which reduces the need for pointers vis-a-vis Java. c) Most garbage collectors also add overhead when updating object references. d) Swift is massively more memory efficient. Fast GC requires 3-4X the memory. [1] https://www.quora.com/Why-doesnt-Apple-Swift-adopt-the-memory-management-method-of-garbage-collection-like-in-Java https://www.quora.com/Why-doesnt-Apple-Swift-adopt-the-memor...
- johncolanduoni 10y agoa. This one smacks of sour grapes. It doesn't help with maintenance when you're dealing with a dense graph, and every time you add a relation you have to check if you need to make something weak. Reasoning about reference graphs is often not intuitive, due to it being hard to see indirect references. Also note that some cyclical structures cannot be broken by statically using weak references, and require special action like specialized manual reference counting (I recently had to implement such a system ). b. Very true, but these are the exact opposite of the cases that I'm talking about. c. Two things: First, memory has gotten incredibly cheap and dense for servers. Server GCs are generally more cache friendly than reference counting (due to both allocation strategies/compaction and the lack of need to touch reference counts), which is important because CPU performance gains are slowing down. Second, the graph he shows (I've seen it before) is looking at older GCs, and more importantly GCs where memory usage outside of the working set was not optimized for. In a paged system, it is of little benefit to ensure memory outside your working set is released. Obviously on mobile the situation is different, but there are also GCs that have far lower memory usage because they have been optimized for constrained scenarios. Android's new ART collector is sort of an example of this, but their efforts were massively undermined by the fact that they had to adapt to all of the existing Android library/app code which uses tons of object pooling. Manual object pooling with GCed objects creates all kinds of problems for GCs, particularly generational ones. I agree with the decision to go with ARC for Swift from a lot of perspectives: Swift's target market is not usually dealing with complex interconnected models, using a GC would make ObjC interop difficult, etc. But it is far from obvious based on this information that it is beneficial to have a language stick with only a GC or only reference counting.
- fpoling 10y agoWorking with cycles under reference counting is not impossible. The key is good memory reporting tools. Yes, sometimes even with tools identifying a memory leak through cycle with reference counting can be painful. However, the fix itself is typically very local and easy to test. Compare that with a C#/Go/Java application after it turned out that GC-induced latency is unacceptable. The fix could be a massive rewrite that makes the resulting code maintenance nightmare. And if in the case of Java there are at least some knobs to tune the GC that could be enough to fix the problem, with Go or C# the code rewrite is the only solution. As for local object pools, they are nice as long as their size is smaller than CPU cache. Without the control on the pull size it is very to easy to accumulate a lot of local garbage that it starts to hurt the performance.
- johncolanduoni 10y agoThe problem with both approaches is how binary they are. GC latency is an issue if the active part of the heap gets too big and/or any strategies you have for dealing with short lived garbage (e.g. generations) get overwhelmed. The simple solution is to give flexibility in how allocations are done. C# does this a bit but makes you pick per type, instead of per instance. Go goes a bit further, but it still only leaves you with the options of stack allocated/containment and GC. What would be ideal is having stack allocated, ARC, and GC all be options in the same program. Another advantage of the task-focused approach is that you can optionally collect the arena if it has gotten too big without halting the whole program (just the running task). In this case, you may have latency on one request but it need not effect latency on other requests. > As for local object pools, they are nice as long as their size is smaller than CPU cache. Without the control on the pull size it is very to easy to accumulate a lot of local garbage that it starts to hurt the performance. How is this different from the ARC case? If your working set fits in the cache, great, if it doesn't, then you'll have problems. If your allocation/release patterns are such that the allocator keeps handing you the same exact pieces of memory, then you're basically doing stack allocation. Not to mention that RC doesn't help the cache-unfriendliness that comes from heap fragmentation.
- fpoling 10y ago
- fulafel 10y agoWith ARC you can still have hiccups resulting from cascading deallocations. (Nit: ARC is a form of GC)
- abalone 10y agoThat seems like a much smaller scale problem than global GC for typical request-based server apps. (And yes you're right, by "GC" I mean mark-and-sweep GC.)
- josteink 10y ago> I wonder whether Java will get displaced by Swift on the server at some point. Anyone want to place bets? Last time I checked developing with swift requires xcode, which requires osx, which requires spending excess $1k on what should be commodity x86 hardware, to have it labeled "a Mac". So a big fat no chance there.
- johncolanduoni 10y agoSwift runs on Linux, and Swift's vim/emacs/atom packages work just fine. Not that I think any enterprise that has tons of Java code will switch to anything ever, much less Swift. But "needs a Mac" is not the reason.
- josteink 10y agoIn that case, O'Reilly better get their act together and stop spreading disinformation in their Swift books[1]. [1] http://www.oreilly.com/programming/free/swift-pocket-reference.csp?imm_mid=0e4c45&cmp=em-prog-free-lp-oseu16_nem1_swift_pocket_ref http://www.oreilly.com/programming/free/swift-pocket-referen...
- johncolanduoni 10y agoWhere does it say it only runs on iOS and OS X?
- josteink 10y agoPage 5: getting started with swift 2 It says xcode 7 or later is required. How am I going to run that on Linux? How am I going to CI that on Linux?
- abalone 10y agoIt doesn't say it's required. Relax, Swift was just open sourced in December so some of the books might still focus on Macs. Watch someone code and run Swift on Linux: https://developer.apple.com/videos/play/wwdc2016/415/ https://developer.apple.com/videos/play/wwdc2016/415/
- chvid 10y agoHow would you write the code (and JCStressTest tool) corresponding to the article in Swift?
- chvid 10y agoTo answer my own question: You cannot. To answer your question: Very unlikely. Swift has a lot of irrelevant complexity from its Apple/Objective-C interop, poor reflection support, poor IDEs (Xcode) compared to established platforms such as Java 8 or alternatives such as Kotlin, Scala and so.
- abalone 10y agoI don't know the exact answer, but Swift takes a higher-level task/queue approach to concurrency, letting the OS handle more of the underlying thread management. So if you wanted to write a concurrency stress test you'd probably write it on top of those constructs.[1] I'm not sure what you mean by "irrelevant complexity". Maybe you could cite some examples. Limited reflection/dynamism was an intentional design choice for greater safety, and there are complaints, but it's not without benefit. And it's a bit hasty to criticize lack of IDE support when it was just open sourced 7 months ago. That's like criticizing Scala for lack of IDE support.. in 2005. [1] see https://developer.ibm.com/swift/2016/02/22/talking-about-swift-concurrency-on-linux/ https://developer.ibm.com/swift/2016/02/22/talking-about-swi...
- jerven 10y agoWhile the constructs are higher level, the compiler still needs to deal with all of this complexity. Normal developers can ignore this. But there will be a memory model and a modern language should specify this. If swift does not have an equivalent idea of what its memory model should be, the ARM/X86 splits will lead to interesting bugs.
- douche 10y agoHa. Maybe if we are talking about geological timescales. Nobody is going to rewrite all those trillions of lines of Java code out there in the wild any time soon. Also with all the tooling built around the JVM, a non-JVM replacement is probably a non-starter. Java is the new COBOL - and it'll be lurking in the guts of big enterprise systems for decades.
- djb_hackernews 10y agoIf your time frame is less than 50 years I'll take that bet. But your comment leads me to believe you haven't used Java in some time. The GC has 100s of man years worth of research and optimization built in to it, Java provides a lot of higher level concurrency like executor services, fork/join, promises/futures, and with Quasar it has Go like goroutines called fibers. Optional is built in to the language as well (and to be honest find them sort of ho-hum, certainly a bizarre reason to stop using a language.)
- pawadu 10y agoSpeaking of Go... would Swift really have a chance against Go on server?
- alblue 10y agoIt's early days yet, but one advantage of having the same language on the client and the server is that you get a lot of benefit in code and team sharing.
- abalone 10y agoI think it's either 5-10 years or never. I am a huge Java user and fan btw, but I am looking to the next 20 years here. Despite much optimization, GC still struggles with memory efficiency and predictable performance in a diversity of scenarios. You have to tune it. I guess you could simplify my comment to two advantages: No GC, and elegantly baking constructs that make programming safer into the language as opposed to things you can opt-in to. While it may be possible to get these things with Java, if it's a lot simpler to get consistent performance, efficient memory use, protection from null pointers, and safe concurrency.. then there may be an opportunity for Swift.
- idobai 10y ago> No garbage collection, so no GC performance hiccups. Swift has ARC(https://en.wikipedia.org/wiki/Automatic_Reference_Counting https://en.wikipedia.org/wiki/Automatic_Reference_Counting) which is a GC strategy. And I don't think it can compete with the performance of the JVM's G1 (currently). > I wonder whether Java will get displaced by Swift on the server at some point. Anyone want to place bets? I'd bet on Scala(http://scala-lang.org/ http://scala-lang.org/) which has far more benefits compared to Swift - OOP+FP, higher kinds, typeclasses, implicits, (hygienic) macros etc. dotty(https://github.com/lampepfl/dotty https://github.com/lampepfl/dotty) will have union- and intersection types with other useful stuff. There is a JS backend(https://www.scala-js.org/ https://www.scala-js.org/) and there'll be an LLVM(https://github.com/scala-native/scala-native https://github.com/scala-native/scala-native) backend too.
- alblue 10y agoJust to be clear: reference counting isn't a garbage collection strategy. It is, however, an automatic memory management strategy.
- hyperpape 10y agoReference counting is a form of garbage collection. [1] https://news.ycombinator.com/item?id=11659863#up_11662144 https://news.ycombinator.com/item?id=11659863#up_11662144 [2] https://en.wikipedia.org/wiki/Reference_counting#Use_in_garbage_collection https://en.wikipedia.org/wiki/Reference_counting#Use_in_garb... [3] https://www.cs.virginia.edu/~cs415/reading/bacon-garbage.pdf https://www.cs.virginia.edu/~cs415/reading/bacon-garbage.pdf