Kotlin for game dev - garbage-collection

Background:
I'm always searching for a language to replace Java for game development. Kotlin looks promising with a good IDE support and Java interop. But one of the FPS killers for a game (on Android especially) is GC usage. So, some libraries (like libgdx) are using pools of objects, custom collections and other tricks to avoid frequent GC run. For Java that can be done in a clear way. Some other JVM languages espesially with functional support using a lot of GC by it's nature, so it is hard to avoid.
Questions:
Does Kotlin creates any invisible GC overhead in comparison to Java?
Which features of Kotlin is better to avoid to have less GC work?

You can write Kotlin Code for the JVM which causes the same allocations than the Java corresponding logic. In both cases you have to carefully check if a library call allocates new memory on the heap, or not. Using Kotlin in combination with LibGDX doesn't introduce any invisible GC overhead. It's an effective way and works well (especially with the ktx extension.
But there are Kotlin language features which may help you to write your code with fewer allocations.
Singletons are a language feature. (Object declarations, companion object )
You can create wrapper classes for primitive types which compile to primitives. But you get the power of type safety and rich domain models (Inline classes).
With the combination of Operator overloading and Inline Functions you can build nice APIs which modify objects without allocating new ones. (Example: Allocation-free Vectorial operations using custom operators)
If you use any kind of dependency injection mechanism or object pooling to connect your game logic and reuse objects, then Reified type parameters may help to use it in a very elegant an short way. You can skip a class as type parameter, if the compiler knows the actual type.
But there is also another option which indeed gives you a different behavior in memory management. Thanks to Kotlin Multiplatform, you can write your game logic as Kotlin common module and cross compile it to native code or to Javascript.
I did this in a sample Game project Candy Crush Clone. It works with Korge a Modern Multiplatform Game Engine for Kotlin. The game runs on the JVM, as HTML web app and as Native binary in Win, Linux, Mac, Android or IOS.
The native compiled code has its own simpler garbage collection and can run faster. So the speed-increase and the different memory management may give you the power reserve to bother even less with the GC.
In conclusion I can recommend Kotlin for Game dev, also for GC critical scenarios. In my projects I tend to create more classes and allocate more memory when I write Kotlin code. But this is a question of programming style, not a technical one.

As a rule of thumb, Kotlin generates bytecode as close as possible to the one generated by Java. So, for example, if you use a function as a value, an inner class will be created, like in Java, but no more. There are also some optimization tricks like IntArray and inline to perform even better.
And as #Peter-Lawrey said, it's always a better idea to measure the values for your specific case.

Technically, your questions comparing Kotlin to Java are moot, they will perform the same. But Kotlin will be a better development experience.
If Java is good for writing Games, then Kotlin would only better due to developer productivity.
Note: the gaming library LWJGL 3 uses Kotlin in part, with GitHub stats showing 67.3% of the code being Kotlin (template module looks to be mostly Kotlin). So asking people who work with LWJGL will give you the best answer to this question since they have a lot of experience in this area.

Related

Why are asynchronous runtimes like Tokio necessary?

My first experience doing a computer system project was building a server using vanilla Java and then a client on an Android phone. Since then, I've found that there are a lot of frameworks to help manage scalability and remove the need to write boilerplate code.
I'm trying to understand what services like Tokio and Rayon enable.
I came across this paragraph on the Tokio tutorial page and I'm having a hard time understanding it
When you write your application in an asynchronous manner, you enable it to scale much better by reducing the cost of doing many things at the same time. However, asynchronous Rust code does not run on its own, so you must choose a runtime to execute it.
I first thought a "runtime" might refer to where the binary can run, but it looks like Tokio just provides functions that are already available in the Rust standard library while Rayon implements functions that aren't in the standard library.
Are the standard implementations for asynchronous functions written poorly in the standard library or am I not understanding what service Tokio is providing?
Rust currently does not provide an async runtime in the standard library. For full details, see Asynchronous Programming in Rust, and particularly the chapter on "The Async Ecosystem."
Rust currently provides only the bare essentials for writing async code. Importantly, executors, tasks, reactors, combinators, and low-level I/O futures and traits are not yet provided in the standard library. In the meantime, community-provided async ecosystems fill in these gaps.
Rust has very strict backward compatibility requirements, and they haven't chosen to lock-in a specific runtime. There are reasons to pick one over another (features versus size for example), and making it part of the standard library would impose certain choices that aren't clearly the right ones for all projects. This may change in the future as the community projects better explore this space and help determine the best mix of choices without the strong backward compatibility promises.

Is Swift resistant against hooking?

Cycript is a console based application that is a blend of Objective-C and JavaScript. Cycript is very useful for dynamic analysis of iOS applications.
If you write any methods or the complete ipa with Swift is it still possible to hook the application on a jailbroken device? Or is Swift safe like "native C" Code on iOS ?
I'm not really familiar with Cycript but I have a little understanding of the Swift compiler.
Swift code will be more resistant to hooking but it should not be completely impossible. NSObject subclasses and Swift classes that are declared #objc should be as accessible as Objective-C code. Pure Swift code, especially in optimised builds would be harder to inject code into because they are often statically dispatched and in many cases will actually be inlined into the calling code.
Where code hasn't been inlined it may may be possible to patch the functions in memory themselves to jump to an alternative function but it wouldn't be as easy as just modifying function tables.
Where key functions have been inlined it may be possible to find and modify each usage if common patterns of code that could be identified and if the function is long enough it may be posible to patch in a jump to an alternate version but this would get really quite tricky.

Are there real world applications that use metaprogramming?

We all know that MetaProgramming is a Concept of Code == Data (or programs that write programs).
But are there any applications that use it & what are the advantages of using it?
This Question can be closed but i didnt see any related questions.
IDEs are full with metaprogramming:
code completion
code generation
automated refactoring
Metaprogramming is often used to work around the limitations of Java:
code generation to work around the verbosity (e.g. getter/setter)
code generation to work around the complexity (e.g. generating Swing code from a WYSIWIG editor)
compile time/load time/runtime bytecode rewriting to work around missing features (AOP, Kilim)
generating code based on annotations (Hibernate)
Frameworks are another example:
generating Models, Views, Controllers, Helpers, Testsuites in Ruby on Rails
generating Generators in Ruby on Rails (metacircular metaprogramming FTW!)
In Ruby, you pretty much cannot do anything without metaprogramming. Even simply defining a method is actually running code that generates code.
Even if you just have a simple shell script that sets up your basic project structure, that is metaprogramming.
Since code as data is one of key concepts of Lisp, the best thing would be to see the real applications of projects written in these.
On this link you can see an article about a real world application written partly in Clojure, a dialect of Lisp.
The thing is not to write programs that write programs, just because you can, but to add new functionality to your language when you really need it. Just think if you could simply add new keyword to Java or C#...
If you implement metaprogramming in a language-independent way, you get a program analysis and transformation system. This is precisely a tool that treats (arbitrary) programs as data. These can be used to carry out arbitrary transformations on arbitrary programs.
It also means you aren't limited by the specific metaprogramming features that the compiler guys happened to put into your language. For instance, while C++ has templates, it has no "reflection". But a program transformation system can provide reflection even if the base langauge doesn't have it. In particular, having a program transformation engine means never having to say "I'm sorry, your language doesn't support metaprogramming (well enough) so I can't do much except write code manually".
See our DMS Software Reengineering Toolkit for such a program transformation system. It has been used to build test coverage and profiling tools, code generation tools, tools to reshape the architecture of large scale C++ applications, tools to migrate applications from one langauge to another, ... This is all extremely practical. Most of the tasks done with DMS would completely impractical to do by hand.
Not a real world application, but a talk about metaprogramming in ruby:
http://video.google.com/videoplay?docid=1541014406319673545
Google TechTalks August 3, 2006 Jack Herrington, the author of Code Generation in Action (Manning, July 2003) , will talk about code generation techniques using Ruby. He will cover both do-it-yourself and off-the-shelf solutions in a conversation about where Ruby is as a tool, and where it's going.
A real world example would be Django's model metaclass. It is the class of the class, from which models inherit from and responsible for the outfit of the model instances with all their attributes and methods.
Any ORM in a dynamic language is an instant example of practical metaprogramming. E.g. see how SQLAlchemy or Django's ORM creates classes for tables it discovers in the database, dynamically, in runtime.
ORMs and other tools in Java world that use #annotations to modify class behavior do a bit of metaprogramming, too.
Metaprogramming in C++ allows you to write code that will get transformed at compilation.
There are a few great examples I know about (google for them):
Blitz++, a library to write efficient code for manipulating arrays
Intel Array Building Blocks
CGAL
Boost::spirit, Boost::graph
Many compilers and interpreters are implemented with metaprogramming techniques internally - as a chain of code rewriting passes.
ORMs, project templates, GUI code generation in IDEs had been mentioned already.
Domain Specific Languages are widely used, and the best way to implement them is to use metaprogramming.
Things like Autoconf are obviously cases of metaprogramming.
Actually, it's unlikely one can find an area of software development which won't benefit from one or another form of metaprogramming.

Security of scala runtime

I'm developer of Robocode engine. We would like to make Robocode
multilingual and Scala seems to be good match. We have Scala plugin prototype here.
The problem:
Because users are creative programmers, they may try to win battle
different ways. As well robots are downloaded from online database
where anyone could upload one. So gap in security may lead to security
hole into users computer. Robots written in Java are running in
restricted sandbox. Almost everything is prohibited [network, GUI,
disk (limited), threads (limited), classloaders and reflection]. The
sandbox is similar to browser applet. We use SecurityManager, custom
ClassLoader per robot, etc ...
There are two ways how to host Scala runtime in Robocode:
1) load it together with robot inside of sandbox. Pretty safe for us,
preferred solution. But it will damage Scala runtime abilities because runtime uses reflection. Maybe generates classes at runtime ? Use threads to do some internal cleanup ? Access to JVM/internals ? (I would not like to limit abilities of language)
2) use Scala runtime as trusted code, outside the box, security on
same level as JDK. Visibility to (malicious)
robot. Are the Scala runtime APIs safe ? Do methods they have security
guards ? Is there any safe mode ? Is there any singleton in Scala runtime,
which could be abused to communicate between robots ? Any concurency/threadpool/messaging which could simulate threads ? (Is there any security audit for Scala runtime?)
3) Something in between, some classes of runtime in and some out. Which classes/packages must be visible to robot/which are just private implementation ? (this seems to be future solution)
The question:
Is it possible to enumerate and isolate the parts of runtime which must run in
trusted scope from the rest ? Specific packages and classes ? Or better idea ?
I'm looking for specific answer, which will lead to secure solution. Random thoughts welcome, but not awarded. There is ongoing discussion at scala email group. No specific answer yet.
I think #1 is your best bet and even that is a moving target. As brought up on the mailing list, structural types use reflection. I don't think structural types are common in the standard library, but I don't think anyone keeps track of where they are.
There's also always the possibility that there are other features using reflection behind the scenes. For example, for a while in the 2.8 branch some array functionality was using reflection. I think that's been changed after benchmarking, but there's always the possibility that there's some problem where someone said "Aha! I will use reflection to solve this."
The Scala standard library is filled with singletons. Most of them are immutable, but I know that the Scheduler object in the actors library could be abused for communication because it is essentially a proxy for an actual scheduler so you can plug your own custom scheduler into it.
At this time I don't think Scala requires using a custom class loader and all of its classes are produced at compile time instead of runtime, but then again that's probably a moving target. Scala generates a lot of class files, and there is always talk of making it generate some of them at runtime when they are needed instead of at compile time.
So, in short, I do not think it's possible (within reasonable constraints on effort) to enumerate and isolate the pieces of Scala that can (and should) be trusted.
As you mentioned other J* language implementations which all may make use of reflections, it would be a ban for all those languages as long as reflection is not part of the game.
I guess that would be JVM's problem not to have a way to partition the scope of reflection API, such that you could sort of "sandbox" the part of code that could be reflected within.

How stable is the Groovy language?

We're writing a large production system in Java, and I'm considering whether or not we can write some of the components in one of the JVM-based dynamic languages. Groovy appears to be the best choice from the Java interoperability standpoint. But is the Groovy implementation reliable enough to use in production (I would assume so), and is the Groovy language specification itself stable enough so that we aren't going to have to revise our production code substantially in a year or two? What are your experiences?
Summary (5/30/09): Good comments, the sense I get is that you should be cautious in adopting Groovy for mission-critical production use, it's fine for ancillary usages like putting together test cases, and there's a middle ground where it's probably fine but do your homework first. Performance is an issue, which needs to be balanced against the increase in developer productivity. Bill and Ichorus have equally helpful answers based on Groovy use, so it was a coin toss.
Update (12/3/09): More recently I've been taking a serious look at Scala, another JVM language. It was designed and implemented by Martin Odersky, the original author of the current javac compiler and the co-designer of Java Generics. Scala is a strongly typed, but uses type inferencing to strip out a lot of boilerplate. It's a nice blend of object-oriented and functional programming. James Gosling likes it. James Strachan, the author of Groovy, likes it too. And Odersky's experience writing javac means Scala's raw performance is not far from Java's, which is impressive.
Update (4/26/11): Take a look at Groovy++, a statically typed extension of Groovy, which has performance equivalent to Java. Looks very interesting.
Edit: Here almost four years later and Groovy has become much more solid.
I can wholeheartedly recommend it for production grade projects.
I've been using Groovy to support production applications for a while and for that purpose it is stable enough. As for actually having Groovy in bona fide production code; I don't think I would do that. Groovy does too many surprising things. It has gotten much better in this regard over the past year or so, but every once in awhile I will run into a bug that is a bit difficult to track down because of the generated code (my issues seem to have revolved around scoping).
I have gotten away from Groovy (though the stuff that we use that is simple and solid is still around) and have used Python (jython implementation), which has been far more predictable in my opinion. Also, python trumps Groovy in readability.
You can write some very interesting code in Groovy with closures and operator overloading and whatnot.
These languages are used for convenience and speed on ancillary code...stuff that can be switched out on the fly if need be. None of it is in production. I don't think I would put either in production unless it was as a stopgap to get something critical out of the door in a major hurry or as a proof of concept or prototype.
And in the case of putting it in actual production, it would have to be in the most dire of circumstances and I would assign someone to rewrite it in pure Java for the next release. I am 98% sure that either would be fine in production but that 2% is too much unnecessary risk.
We've got several production apps running on Grails (using Groovy as the language). So far, no issues have resulted. As for JVM compatibility, take a look at how little the JVM byte-code has changed in the last 5 years... like 1 instruction was added, and none were made obselete.
Will new versions of Groovy come out in the next year? Yes. Will you be required to change to them? No. Though you might want to, 1.6 is a huge speed improvement.
Which brings us to the major drawback of Groovy, the speed issue. Obviously, Groovy is slower than straight Java. The current number are up to 10 TIMES slower, for certain actions. That said, is your CPU the bottleneck in your app? For us, it's mostly DB access and latency. If it's the same for you, what matter if the CPU spends 200ms processing the page request instead of 35ms?
Is that the only problem with Groovy? Nope. Dynamic languages have refactoring difficulties, since there isn't necessarily a complete class specification anywhere in the code. However, this is partially balanced by the smaller code-size which makes it easier to find the places to modify the code.
Anyway, Groovy is a perfectly fine language for production uses. Mix it with Java for your "critical" code, if you fear the reliability. That's the BEST part of Groovy... how easy it mixes with Java classes.
I'm currently exploring using Groovy for only writing unit tests. This has the effects of
Allowing the potentially tedious part of writing tests to be done in a syntax that is a bit simpler than Java.
Keeps the Groovy code out of production.
Allows a large portion of the code base to be written in a non-Java language.
Of course, we haven't started yet, but this is at least my way of attempting to introduce alternate JVM languages to our new projects (and possibly existing ones). I have the same concerns you do, and even more so around performance than stability.
Scripting languages evolve "too fast" in the aspect of syntactic features.
If you want a language for the JVM that will stay compatible for
many years,
Java is your only choice ;)
By the way, I don't think that the readability of code is
ensured by a scripting language automatically.
We used Grails/Groovy as our primary backend at my previous company, and from that experience I'd say that I would choose Groovy over Java in most circumstances I am likely to encounter, since it interoperates with Java seamlessly and is otherwise more fun and expressive. Additionally I would expect the database would almost always be the bottleneck of my application rather than language performance, and we didn't encounter any stability issues/bugs with groovy as far as I recall.
But personally it's usually not about Groovy vs Java for me in most cases -- it's about Groovy/Java + available libraries vs. other languages like Python/Jython/JavaScript/Ruby + available libraries. And there are a lot of other considerations there such as strength of community, maturity of relevant technologies for your particular application, etc. In particular, for web development, Grails was decent, but the community seemed lacking. My overall opinion is that I would use python or Node.js going forward. If I needed the JVM I'd use a jython-compatible python web development environment.
I've been playing with Groovy for a month or so. The simplicity is awesome, and the dynamic language features are really cool too. However, speed is definitely an issue. Also, the groovy console really sucks. You cannot do things that you can do e.g. in python. Every once in a while I have to restart the console, reimport, things, etc. It also keeps forgetting the values I put in the variables while in the console mode; somehow mystically they go out of scope. (Is it because of the JVM? I don't know.) I cannot come up with an example from the top of my head, but the behavior I get in the Groovy console is different from the behavior I get in the Grails console, and is different from what I get by just writing code in a script.
A few more warnings. Note that Groovy is almost, but not 100% compatible with Java. For example, this will not compile:
public class HelloWorld {
public static void main(String args[]) {
System.out.println( "Hello, world!\n");
}
}
Also take a look at How to get classpath in Groovy?

Resources