BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Presentations Does Java Need Inline Types? What Project Valhalla Can Bring to Java

Does Java Need Inline Types? What Project Valhalla Can Bring to Java

Bookmarks
51:32

Summary

Sergey Kuksenko talks about the performance benefits inline types bring to Java and how to exploit them. Inline/value types are the key part of experimental project Valhalla, which should bring new abilities to the Java language. It's a story not only about performance, it's also a story about safety, abstraction, expressiveness, maintainability, etc.

Bio

Sergey Kuksenko is a Java Performance Engineer at Oracle working on a variety of Java and JVM performance enhancements. He joined Oracle in 2010 and OpenJDK/OracleJVM is the third JVM in his experience. He started working as Java Engineer in 1996 and as Java Performance Engineer in 2005. He has had a passion for exploring how Java works on modern hardware.

About the conference

Software is changing the world. QCon empowers software development by facilitating the spread of knowledge and innovation in the developer community. A practitioner-driven conference, QCon is designed for technical team leads, architects, engineering directors, and project managers who influence innovation in their teams.

Transcript

Kuksenko: I'll talk a little bit about Project Valhalla, a small part of it, about Java and inline types, and about everything. Before I tell you any other word, I have to show you that slide. It's probably the best slide in any Oracle presentation. That slide gives me full freedom of speech. I can say anything. My name is Sergey Kuksenko. I work at Oracle. I work on Java performance. My goal and everyday routine is making Java faster, whatever that means, in different projects.

Demo

Before we start really talking about inline types, what we did, what we got, what we are going to get, I just want to show you one demo. I wrote it quite simply. Has everybody heard about Mandelbrot set? Right now, I'm executing two different JVMs with almost similar Java programs and showing you results. It's a Mandelbrot set. It's real-time calculation of each frame. Here you can see frames per second in either versions. The first one label does reference, it's old, classic Java, and new label did inline value, it's using inline types. The same, we count that use complex numbers. That scene on each frame and how many frames per seconds I can get on my laptop, with that particular one. If I'm using a big machine I can even get much more real data. The only difference between these two programs is just that seven characters, six characters for the word inline and one space. That's all, totally. It's a new feature which we are introducing for you, inline classes. It's not done yet but I think it's already reached a mature level which we can talk about, and discuss, and show its results.

What Is Valhalla?

In general, what is Valhalla? Valhalla is quite a large project in Java, it's been continuing for years. The idea of Valhalla is to provide new features to get a better memory latency, to get a better memory density and new features to exploit it on a Java layer. It's not a single project, it's like an umbrella we had for a lot of sub-projects. There's other small sub-projects, some cleanup inside Java. We did Nestmates under umbrella Valhalla project, that's already in my trunk. We are providing new inline classes and we are going to make a generic specialization, because without generic specialization inline classes will be much less useless than that. Also, we have to work with that, and provide library migration. Right now, we almost did inline classes. If you read about the health news, for a long time it was called value classes, and less than a half year ago it was renamed to inline classes. The question was, why? The explanation is simple, if you open Java language specification and JVM specification, and just do a grab by word value, you will find in one case 1010 results of that word, and another case 800. Add a new entity and call it value, you'll just create a mess in specification. That is why another name was chosen, right now it's called inline. Maybe it will be renamed in the future. It's not frozen yet, but right now we're stuck with that.

Object Identity

What's the difference between our normal classical, old style class and inline class? The problem is the identity. It was decided that the identity is the root of evil. Wikipedia tells us that's not only in computer science. Identity gives a lot of things. First of all, identity means that object has some unique things, which are virtually and theoretically injected by the place of that object creation. I have one string and the other string have the same context but different strings, different objects, because they were created in different places. I can distinguish it just by == operation and know that. Also, beneath that there are a lot of other things like synchronization. It creates issues, to work with it, to deal with it. Almost in all cases we have to allocate that object in a heap. The question is, can JVM eliminate it? What do you think? Nobody knows.

Participant: What do you mean would eliminate it?

Kuksenko: I mean our issue, not the identity. Our issue is that identity leads to heap allocation, can JVM eliminate heap allocation? JVM of course can. There is escape analysis. I did an explanation for that area. I entered in ACM libraries and tried to do search by some keywords for that word. Escape analysis, I found approximately 8000 articles. For synchronization dimension, which is related to that, I also found nearly 8000 articles. For different types of keywords I found approximately everything is around 8000 articles. Probably, it's the same articles because of its related techniques, related ideas. What does it mean? It means that in 25 years of Java's existence, we have 300 articles per year. First of all, it tells us that there is a high demand for that. The other thing is that it can be done really, a lot of ideas have been raised in this area. The other thing is it's hard to implement. We can't implement the ideas expressed in 300 articles per year. It's a very high rate. The other thing is that it's not enough. There is no final solution. Every article is slightly better than the other in some different aspect. There is no silver bullet for that. That is why we decided not to try to invent and imagine something very smart, or artificial intelligent beneath JVM, thinking about that. We decided to ask your help as Java developers to tell us where that identity is needed for your application and where not. When it's not required by your application, you tell us and we may eliminate heap allocation and save that object.

Inline Class

What is inline class? A little bit, the purpose of that class. It's immutable. It has no null value for inline classes, of course, because if you have a null value you have to make some reference. If you have reference, you have to allocate it somewhere. We only have heap. Java is a very strange language, we have no pointers, but we have null pointer exception. We have no stack but we have StackOverflowException. What is inline class? Inline class is a complex number which is used for Mandelbrot set. What do I have here? First of all, it's a final class. You can't extend inline classes. It's immutable. All fields inside are final. You shouldn't write it but it implies.

The nice feature of an inline class is that an inline class may implement any interface, whatever you want. It will definitely extend everything that we do with that. Right now, inline class should extend objects. There is no deep dive hierarchy here. It's some requirement, some limitation for that thing. That may be changed. Right now, there is a large discussion. It is not done yet. I can't provide any details about that. There is a discussion to make that limitation weaker, to allow an inline class to extend abstract classes. Not every abstract class, but pretty well shaped abstract classes. Right now, it's just a theoretical discussion for specification on how to formalize it, but we're still stuck only with objects.

What do we have to do with some operations which can be applied to objects on any other classes, but requires identity? First of all, what do we have to do with operation, reference equality, ==? We consider different options like make it always false, just deny that operation. We decided that everything is a bad idea. The semantics of equality operations significantly changed for inline classes. If for reference class, I'm just comparing that it's the same references. For inline classes, I have to make a deep comparison. It's called substitutability check. I recursively compare all fields. If it's fields in inline classes, it should be recursive, just to make a == operation here.

What else? An inline class, does it mean that it will be happily allocated on stack? We don't have stack in Java, but we have stack on compiled code. It doesn't mean that it will be happily inserted into upper class. It just means possibility, all decisions on how inline classes will be allocated, where it will reside, what will be done, it's just a JVM decision. Because if you are some third-party JVM vendor, and you want to support JVM inline classes, but you don't want to implement anything serious, just support new operation and allocating the heap, it will work according to specification, but it won't give any performance benefits, of course.

There's quite an interesting feature, and it already has a huge impact on performance, is arrays. The way you find things that we may create in a flattened array, so-called, when we don't have references as we have before with class. All those inline classes are injected into an array, and no dereferences when we're working with that. It's all inside our flattened arrays. We considered to make it a separate type hierarchy but it's very ugly. The problem is we can't reuse all existing Java libraries, which are our key assets really in Java. The current solutions that flattened arrays, arrays of inline types are covariant with object arrays. You reference to a flattened array, maybe assigned to object array, and we have to deal with that.

Boxing vs. boxing

Another situation, initially, of course, for every inline class, should be created some heap companion, some heap [inaudible 00:12:46], heap for that object. It looks like a boxing int even for some period of time, it was called boxing but right now it's not called boxing, why? Primitive type int doesn't have any identity. It has no allocation. It's just a set of values and the operation with them. When you box it into a Java lang integer, you get all the full set of identities there. A lot of Java puzzlers, how to trick something with integer cache, which resides inside integer class. You may even do synchronization on integer class, whatever is required for that object. For inline classes, having one inline class compare without identity operations, and other boxed to its identity operation indicates a total mess, really. It won't work anyway. Right now, if we created some heap allocated companion for our inline class, it's still inline class, and it won't get an identity. All semantics of all operations like synchronization, equality will remain the same. It doesn't depends where our inline class resides. It's a key thing of that stuff. That's boxing conditions.

Before talking about that, it was a very short introduction to inline classes. In the internet there's a lot more detailed descriptions of why such solutions were done. I'd like to talk about performance, what we have already at that point. The key goal of inline classes, value classes was to make some things which code like class and to walk like an int. Let's just check, if we get it or not.

Local Variable

That is Mandelbrot set code. It's just simple iteration for one complex number and checking. Does it fit into the Mandelbrot set or not? That's measurement results. It's average time in seconds, then shorter bars is faster. The implementation, classical [inaudible 00:15:09] implementation. You can implement right now. Hand-made primitive types implementation just to check, did we lose something when we were making an inline class, and inline class implementation? Here we can see that inline classes work really like a primitive class by performance. Just heap allocation in bytes not objects per second, but bytes on one iteration for such an operation. We have to carefully pinpoint all small operations around our classes.

Mandelbrot

Just forget about Mandelbrot, just compare that for 500x500 frame. It shows a very significant reduction of all kinds of CPU misses and provides a better performance.

The next picture will be much more interesting. I took large server machines, not in my laptop, with 64 cores and checked how it scales, the same Mandelbrot set, which I've shown you. It started here with one core using inline classes slightly higher than reference classes. Reference on that machine got approximately 30 operations per second and throughput has been better, and inline classes got approximately 16, less than two times faster. When I was increasing the amount of cores, amount of threads in my machine, I've got a very huge speed-up for inline classes. Finally, on 64 cores it provides 60 times faster performance than classical reference classes. I got it, just write one UQ word into Java program. I was also checking how it parse through parameter colon convention, what we need. It works like an integer without any concerns.

Array Access

Here's a picture from one side it's classical array, we have a reference class with some fields and we have flattened array. I'm trying to access some field here. Again, chart with three values, reference, primitive, and inline. For random access inline completely mirrors these primitive type performance. The same for sequential access, when maybe hard to predict may help to reference classes. Here it helps. It's not so awful like here, like just look on the y-axis. It's magnitude of numbers. Predictor helps but, anyway, primitives and inline classes are faster.

Collateral Damage in Legacy World

I have to say a couple of words about the next section, what I'm going to tell you here. First of all, we changed the semantics of some operation in application to inline classes. Inline classes has no synchronization, equality works different. Array of objects may be in reality array of inline classes, maybe flattened, maybe not flattened. Everything induces runtime checks into your Java program. I'm even working with non-inline world, with objects, interfaces, where inline class can be hidden. It means that I have to check it at runtime. It means that in reality, I introduce some slowdown for old legacy. I've got legacy, everything was written without inline classes program. In my history, probably it feels Java project at all in the whole history, when we are adding a new feature and it may cause slowdown on old features. Not a good idea, but just to tell you what we got and how we are going to manage that. In reality, I don't think that it's really awful. A lot of issues were fixed. A lot of issues will be fixed. We know how to do it right now. Some snails required evaluations.

Inline class may enter into reference world. You may assign inline class into object, into interface. Also, we have a so-called reference companion which, name.ref, naming for that. It will be really reference which parses different your program and work with that. Somehow we have to deal with that.

Reference Comparison

Let's start from compare. How to make a reference comparison before. Right now in Java 14, you just compare reference. The other side, you can see what we have to do in case of inline classes. First of all, we have to be sure that there are no inline classes there. If there are no inline classes there, it's fine. Go with the old way. If there are inline classes, much work should be done. How to know in runtime if the class is inline class. Obviously, we can go to class descriptor which is available through object header, and check that it's inline class. In that case, we have to do two dereferences, and probably we'll get two cache misses, and probably we'll get a huge slowdown, in comparison to what we did before. Maybe it makes sense to move that information about inline class a little bit closer to our object. Every object has a header in Java, in our OpenJDK Oracle implementation at least. That can consist of two words, so-called Mark Word, which contains different bits of some internal information and class pointer which reference to class descriptor.

Let's try to find the place inside the Mark Word. It's a nice idea, we will save a lot of performance here. It's a part of HotSpot code which describes usage of bits inside Mark Word. Really, it's a very difficult place. Even there is a fight between different Java teams fighting for that bit. Because there is no bits for everyone, for every team, for GC team, runtime team, compiler team. He wasn't able to find a single bit for it, but he was able to find a pattern which is not used by anyone else. It's so-called [inaudible 00:21:57], inline class can't be locked. It's our pattern to marking that it's inline class. Even checking a pattern instead of single bits is much better than going to class descriptor and check it.

Let's check in the code. A very simple code, just compare it to references and check which assembly we got. That is the assembly for the old pre-Valhalla world, just comparison, increment, decrement, we are done. Here's what we got in Valhalla. It's quite simple. First of all, check reference. If there are equals we are done, if not equals, check if it's no, at least one of them, the first test. The other apart, that is 405, it's our magic pattern for inline class. Go to other checks, and if everything is fine, we insert our invokedynamic with call substitutability check. When I'm talking collateral damage for legacy world, I mean how big an influence it has for non-inline classes. If it's not interesting, you don't want to talk, to think about inline values, we just try to understand how previously our code worked. If you don't have inline classes, your code will never execute that Mark it as value world. Reference world also becomes complicated.

The other issue we found, because if you have invokedynamic instruction in your loop, it won't be unrolled by HotSpot JIT compiler. It's not a bug. It's not an issue. It was not required before. It's just not yet implemented. We know it and we'll do it in the near future. Here is a comparison for references, reference equality comparison, in current state and in Valhalla world. Just references, no inline classes as I told. For baseline, I have to show two pictures with a loop and roll, and without loop and roll. Because in Valhalla, we still did not implement loop and roll. There are some points when we have two times slowdown. There are some points when we don't have slowdown. In general, checking something large, it spreads everywhere and doesn't code a lot for us. We are still working on it. Synchronization, the same what we are doing right now, what we have to do in the future for that. The same inline check. Not an issue at all. A lot of benchmarks were checked, it's less than 1% difference. It's not a huge number for synchronization issue.

Arrays (Object[])

Array access, as a huge part of activity it should be done. Because of foray, we have to check if it's an array of references. If it's an array of inline type, but for inline type, that array could be in two states, it could be flattened, it could be not flattened, and not flattened, not allowing null inside it. Different checks. Again, somehow we have to insert that information inside our array object. Array also has header, a little bit larger than ordinary object header because we just have to add length. We can't encode all required information inside class descriptor here because of the same inline class, could be flattened or not. We don't want to create two class descriptors, it would be a mess. We need to find a place in the header for it. There is no more place, there is no more room in Mark World. We decided to tweak this class pointer. In reality, class pointer is a waste of space. It's 32 or 64 bit reference, it depends on the environment, how we're using compress tools. Even for 32 compress type references, you cannot create application of each required in reference to class descriptor using a high bit. There are no such applications in the world. There are no such machines in the world which can raise a huge amount of classes. At least we borrowed a couple bits from a high place of class pointer. What does it mean? It means that for every access to array if you have to do something with class descriptor of an array, or even object, if you don't know, is it array or not? You have to clear that bit to get a proper pointer to our class descriptor. It will also induce some performance regression. HotSpot is a really fine eliminator, when it's possible.

What do we have to do for load? We have to do more work. The same for store, just to compare all action which we need to perform to deal with that end. It's a large part of work. A lot of which should be done. We are not finished yet, but the current status is, it's good. Good enough for current status. We already eliminated a lot of performance regressions. Right now, some benchmark, we're just tracing our access. There are some benchmarks which show 10% regression, and it's huge. We are working on it. The key problem here, it's not just something unsolvable or something inherently wrong with that idea which we've done in value types. Making Java, how it spreads through our old classes separation. The fact that such optimizations which we already know, they were not required in Java world before, for years. If it wasn't required, we don't have it. We just have to add in your own limitation, which will solve many things.

Inline vs. inline

Another very interesting impact for old legacy world, just arrays equals, compare two arrays. I did a very short array, it's just 1000 reference. Only the last is different. I'm checking array equals performance. We know that integer is not an inline class. It's a concrete class, exact class. Int arrays also, exact class arrays. No inline class can be there. All checks about inline classes, they're completely eliminated by HotSpot, if HotSpot sees that an inline class can be here. Right now, inline class can only be in object reference or interface reference. For objects and interface, runtime checks remains. For exact classes there are no runtime checks and slowdown. I've got that. It's time, then shorter, then faster. For Valhalla and non-Valhalla world, no inline classes at all. Who may guess what I get here? Why it's almost 50% slower?

Participant: Is there the unrolling issue that you mentioned, not unrolling once you enable Valhalla?

Kuksenko: No. It's a comparison of inline tree between two versions of Java. In the first case before Valhalla, we just simply inline array equals object, equals inline everything, type loops unrolled, everything fine, and simple operation. In case of inline, Valhalla arrays equals wasn't inline, previously compiled code is used. Previously compiled code, generic arrays equals objects, all runtime checks remains there. It wasn't inline because of that. If previously, we need all these 350 instruction in our code just to generate array equals. Right now it's six times larger. Occasionally, just coincidence, in our inline heuristics, one of the boundaries when we make decision inline or not inline, it is 1000 bytes for generated code, and we cross that inline heuristic. That is why that method wasn't inline. It also may cause some performance slowdown. We know about that issue. Something will be done. Right now, we even don't bother about it, and we don't work on that inline, because it's clear. Somehow inline heuristic should be improved. It's not related to Valhalla, and idea to inline type, it's some deficiencies of inline heuristic inside HotSpot, to be improved.

Current Status

The general picture of what we did is we checked for Valhalla, our old benchmark base which we have in Oracle. It means it's an old benchmark. There are no inline classes here. Everything we need for that we need to be sure that we don't cause any significant regression for end user application, where we make Valhalla public and turned on by default. For large benchmarks, it's a very nice picture. We have some 2% JITing. It's very hard to dig into large benchmarks, so we prefer to start from micro benchmarks. There is a high probability that when we fix something in micro benchmark, everything will be fine. It will become fine in large benchmarks, so mostly concentrated here. The picture is fine. Majority of benchmarks don't feel anything about inline classes, and all we've down. It was some regressions fixed, and there are some regression on fly. Here, I'd like to ask you to play with that. If you have enough courage, just take Valhalla build, play that with your application.

You don't have inline classes, but your application may create some patterns, which are very bad for inline classes and it's not expressed in our code base. It's obvious that you have much more calls on Oracle. If you check that and write to us early about that, it will be very helpful to avoid that issue and solve it before. In the future, I can't predict when. Maybe it will happen in the next release of Java. The next release in September, not March. You won't need to download a separate Valhalla build to play with value types. Maybe it will be so-called preview feature inside the mainline JDK. It will be. I just can't say when because our schedule is quite flexible. It's really interesting to check that.

Brighter Post-Valhalla Future

I've shown you that inline class rocks as it's designed. I've shown you how it may cause some performance slowdown. I didn't find anything awful in that area right now. Right now, I've just shown for some application, for some small patterns which may be improved for your code using inline class.

First of all, inline class is extremely useful for any kind of arithmetic types. Any kind of arithmetic types like complex numbers, we get a huge speed-up in that situation, other things. I played with some ray tracing, vectors application and rendering, just writing inline keyword not doing any other performance tweaks and only from that, I've got rendering some scheme with Duke. It was speeded up from 55 seconds to 30 seconds. Nice results.

I'm playing with HashMap, but I will talk about optional. Optional will be inline class. Java.util.optional is our litmus test on how we provide migration for classes. Because it was designed as intended to be inline class, it will be inline class in the future. Let's check it. To check it, we have to stress something. I don't like stressing simple optional. It's not useful. I think that theoretically, improving HashMap API [inaudible 00:35:27] will be useful. Because right now, everybody agrees that having such kind of get method which return null when we don't have that key inside our map was a bad idea at the beginning of Java. The best API theoretically, right now, is having a HashMap method get for a key which is optional. Optional will tell us that there are no such key inside our HashMap. I did it manually by hands and checked performance for optional, which is reference optional, and future optional, which will be inline type. It's time in milliseconds for 1 million keys from a map.

Example: Map with Complex Key

A very frequent task, which I have to do in a lot of projects, I have to provide mapping from some set of keys, tuple of keys, like some complex key into some value. I know that there are only two ways to implement it. To introduce object composite key, which will wrap all the things, or create map of map of map of map. Also, obvious way. Does anyone know a shorter way? Just tell me. I'm curious. I'm interested. Maybe a short way will be better than any other. Which way is faster, to make a composite key, or make a map of map of map of map, right now?

Participant: Composite key.

Kuksenko: I'm talking about get operation. If you're doing get, we have to create and to allocate a composite key. If you have a map of map you don't have create, you're extracting just every map by key narrowing the situation down. Interesting fact, the maps at the end of chain is smaller and have better cache localities than the whole map.

Example: Map From

I just implemented always, I did map of map, composite key reference, and composite key inline. It's obvious that inline will provide better performance, and map of map is faster than composite key but map of map is very ugly code, honestly. It's not clear. It's buggy. I prefer using composite key. It's very nice.

Iteration

I like HashMaps. If I take HashMap with a million elements and try to iterate through values and just count integers, which I put into the HashMap. In some situations, I can realize that I've got very different performance for that. It's not expressed here, it depends on upper condition. In the application, you really may get those two kinds of performance: lucky case and unlucky case. The difference between is very huge, 20 milliseconds, just to iterate through values for that. A little bit of digging here shows that for a loop it iterator, and the difference is when escape analysis colorized our iterator. When it was colorized, we enter into lucky case. If iterator wasn't colorized and it was allocated on heap, you got unlucky case. I have 1 million keys and value pairs iterating through them. I have one iterator, I create one iterator. How the creation of one small iterator may cost me 20 milliseconds here. A little bit evaluation shows the problem inside that iterator. Iterator has a state. State of HashMap iterator has references. Those references update on every step, on every next, because I'm updating that state. If I update reference, I have to write GC write barriers. It's not the cost of allocation, it's cost of GC write barriers. If my iterator was colorized, it means the state of that iterator located on a stack inside [inaudible 00:39:53]. In that case, I don't need to invoke to see write barriers. It's not cost of allocation. It's cost of write barriers that we have to deal with. That's a problem with iterator.

Let's try to learn something new. Let's invent some cursor, not iteration. It's immutable, here we interface, but it doesn't matter for us in this situation. It's immutable, we can't change the state of that code. We just ask the next one. How will it work, for example, the next cursor? We implement it, we use inline classes. We always get the same performance as expected without having the lucky or unlucky case with escape analysis. Because escape analysis is a very lucky thing. You can't rely on it, unfortunately.

Move/Copy Data

What is an application? What is a program? Every program is just moving data from one place to another with some transformation, but nothing more. It's our key purpose what we are writing, moving in. How much does it cost to move something in reference class, or inline class? Because for every class I may move only reference. For inline class I have to move the whole inline class which is larger, and maybe much larger. It depends on you. I just decided that checking sorting of arrays will be a very nice idea to checking how moving data works. Sorting is a cost of moving. I implement sorting similar to what we have in JDK. I did some tricks with even a special idea like sorting primitive indices before, and only that will move that data. For that test, the compare to operation was as small as possible because the idea was to check the cost of moving data. Moving data has a huge impact for our performance.

I got a lot of data. I checked it for different classes. I checked for class sizes 8, 16, 24, 32, and 64 bytes, different sizes. For reference class I always move reference in that case, for inline classes, I move a different amount of bytes. I've got a lot of pictures I can't fit in the same picture, and show you for different sizes. Small arrays all fit into L1 cache, red one is reference, blue one is inline classes. Green is trying to avoid that problem with large data and move only primitive indices before, and after that, rest array. For small data, inline classes wins. It's time in microseconds for average time for sorting, and it's always better. I increase my array by 10. Right now, all arrays can't fit into L1 but they fit into L2. It is the same for large inline classes, 64 bytes. There is some mess at the end of that picture. Anyway, inline wins. I increase it by 10. Right now, we fit only into L3 cache. What do we get here? Finally, reference wins. Somewhere for large classes and somewhere only in that situation. I increase more. We don't have enough caches, and references began losing again. Right now, we are getting that indices became a win over inline. When we are inside cache, we don't need to play with any indices, because of strictly for over the lines went faster. The last chart showing for very large amount of classes, much more than any caches, eat all our memory. Anyway, inline classes [inaudible 00:44:31] just straightforward within inline classes for our sorting, is better than the references.

I say that if my data is denser and more local, and resides in a memory, the size of that memory, the size of the data which I have to move means much less than that density. Density gives you much better performance benefits. We got it. Finally, we are bringing a new feature which provides very interesting performance benefits for Java, and hope soon you will be able to check it.

Here are some interesting links which you can do. Everything is done in open source. If you're curious you can read it.

Questions and Answers

Participant: When do you think it will be completed and will be released?

Kuksenko: Project Valhalla is much larger. The two key features of Project Valhalla is value inline classes. The second feature is generic specialization. We separated it because if we design inline class in such a way that generic specialization will fail on it, somehow, we fail completely. We have to make inline classes check that it works for migration and to provide places to be sure that it will work for specialization. That is why right now we were concentrated on inline classes. Honestly, in history, we have five or six, I already lost count of the prototypes, different ideas and prototypes with different models. Finally, you'll find existing solutions. Only right now, only half a year ago, inline classes reached that level of maturity and our expert group moved to specialization, because of that, features should be shipped together. We may show you inline classes, you may play with that, but it still will be a preview feature. Let's wait for generic specialization for that.

Participant: Do you intend to use inline classes the way current case class is for pattern matching?

Kuksenko: Inline class is just a class. Because the guy who is designing pattern matching and the guy who is designing inline classes is the same guy, I think it will be suitable. I don't think that pattern matching will have something specific for reference classes. Inline class is a class so it can't be used for pattern matching at all.

Participant: You're going to provide constructs?

Kuksenko: I don't think any issue for that.

Participant: Inline classes are going to be final?

Kuksenko: Yes, inline classes have to be final.

Participant: It breaks extensibility when you think of the Java universe.

Kuksenko: Inline classes shouldn't be expansibility.

Participant: If you think about the Java universe, it's made up of lots of platforms that extensibility is built into those platforms, and you could do it for the large enterprise type of applications, you're going to have persistence, objects that are not going to be immutable decisions. Do you have a sense where inline classes are going to be useful? Like I said, we can't extend them, so what kind of classes you need to see where this is going to be very useful.

Kuksenko: We understand that maybe theoretically it could bring that. First of all, making the inline class extendable, I can't say that is impossible, but it will bring much more difficulties with very doubtful benefits. Because the idea of inline class is sweep all that small garbage beneath, our small objects which eat a lot of memory because they are spread and they have large and useful data inside our class. It's not the idea to be a primary, very first citizen of Java. It's utility classes. I showed an example of how it might be useful, like any kind of arithmetic, summing total data structures, something with some local things. The problem is that such small local things right now, they produce a lot of hidden Java, and sweeping that and leaving old large objects as plain legacy objects as it is right now. It won't give you a lot of benefit anyway.

Participant: [inaudible 00:49:53].

Kuksenko: I don't think that will be the idea. Inline class should be final. You may lay out for a non-hierarchy. You can do it with runtime but we are not JavaScript, we are not going to compile everything in runtime and do flexible runtimes, because of performance. Making inline class extensible will induce performance slowdown. From my guessing point of view right now it will be very huge slowdown. We don't need it. We don't want it. We will need that feature if it will cause a slowdown. Our goal is performance. The idea of that project is performance.

Participant: You mentioned the optional with inline type?

Kuksenko: Optional will be inline type, yes.

 

See more presentations with transcripts

 

Recorded at:

Jul 15, 2020

BT