Kryo serialisation in Chronicle Map - slow byte reading - scala

I'm using Chronicle Map extensively in Scala and recently decided to experiment with Kryo serialisation. I added custom marshallers (code below) and while it reduced the size of my stores by 14G (roughly 62%), and everything still works, the speed was unacceptable.
I created a sample usecase and did a few runs on the same data
[Using kryo] took 6883, and then 7187, 6954, 7225, 13051
[Not using kryo] took 2326, and then 1352, 1493, 1500, 1187
So it's several times slower. Here's the marshaller for reading:
class KryoMarshallerReader[T] extends BytesReader[T] {
val kryo = // Reference to KryoPool from Twitter's Chill library
override def read(in: Bytes[_], using: T): T = {
val bytes = benchmark("array allocation") {
new Array[Byte](in.readRemaining().toInt)
}
benchmark("reading bytes") {
in.read(bytes)
}
benchmark("deserialising") {
kryo.fromBytes(bytes).asInstanceOf[T]
}
}
override def readMarshallable(wire: WireIn): Unit = {}
override def writeMarshallable(wire: WireOut): Unit = {}
}
I then averaged execution times (all in ms) over those three stages and realised that reading the bytes is the slowest:
stage Average time (ms)
(fctr) (dbl)
1 [array allocation] 0.9432907
2 [deserialising] 0.9944112
3 [reading bytes] 13.2367265
Now the question is - what am I doing wrong?
I looked through the interface of Bytes[_] and it looks like it reads bytes one by one - is there a way to use a buffer or something magically capable of bulk loading?
Update: Eventually I changed array allocation + reading bytes to in.toByteArray but it's still slow because under the hood it copies bytes one by one. Just running reads on the map shows that byte reading is the bottleneck:

in.readRemaining() of the Bytes, passed into BytesReader.read(), is not your object in serialized form, it's more than that. The serialized form of your object is guaranteed to start from in.readPosition(), but it typically end much earlier than in.readLimit() (as readRemaining() = readLimit() - readPosition()). Generally BytesReader/BytesWriter pair of implementations should care of determining the end of the object bytes itself (if it needs), e. g. see the implementation of CharSequenceArrayBytesMarshaller in BytesReader and BytesWriter section of the Chronicle Map tutorial:
public final class CharSequenceArrayBytesMarshaller
implements BytesWriter<CharSequence[]>, BytesReader<CharSequence[]> {
...
#Override
public void write(Bytes out, #NotNull CharSequence[] toWrite) {
out.writeInt(toWrite.length); // care about writing the size ourselves!
...
}
#NotNull
#Override
public CharSequence[] read(Bytes in, #Nullable CharSequence[] using) {
int len = in.readInt(); // care about reading the size ourselves!
...
}
}
But since your are implementing Kryo serialization which should be conceptually similar to Java standard serialization, you should probably take the source of SerializableReader and SerializableDataAccess and modify it to use Kryo instead of standard Java serialization (but note that those sources are LGPLv3 licensed). In particular those implementations use Bytes.inputStream() and Bytes.outputStream() to bridge the standard Java serialization, which doesn't know about Bytes, but knows about InputStream/OutputStream, without needlessly copying bytes. I'm pretty sure Kryo supports InputStream/OutputStream as well.
Be very careful with kryo as an instance field of any serializer interface (BytesReader in your case) without implementing StatefulCopyable. You may easily introduce concurrency bottlenecks, or concurrency bugs (data races). Check Understanding StatefulCopyable section in the Chronicle Map tutorial and Chronicle Map custom serialization checklist.

Related

Scala.js - Convert Uint8Array to Array[Byte]

How do I implement the following method in Scala.js?
import scala.scalajs.js
def toScalaArray(input: js.typedarray.Uint8Array): Array[Byte] =
// code in question
edited per request: tl;dr
input.view.map(_.toByte).toArray
Original answer
I'm not intimately familiar with Scala-js, but I can elaborate on some of the questions that came up in the comments, and improve upon your self-answer.
Also I don't quite get why I need toByte calls
class Uint8Array extends Object with TypedArray[Short, Uint8Array]
Scala treats a Uint8Array as a collection of Short, whereas you are expecting it to be a collection of Byte
Uint8Array's toArray method notes:
This member is added by an implicit conversion from Uint8Array to
IterableOps[Short] performed by method iterableOps in scala.scalajs.js.LowestPrioAnyImplicits.
So the method is returning an Array[Short] which you then .map to convert the Shorts to Bytes.
In your answer you posted
input.toArray.map(_.toByte)
which is technically correct, but it has the downside of allocating an intermediate array of the Shorts. To avoid this allocation, you can perform the .map operation on a .view of the array, then call .toArray on the view.
Views in Scala (and by extension Scala.js) are lightweight objects that reference an original collection plus some kind of transformation/filtering function, which can be iterated like any other collection. You can compose many transformation/filters on a view without having to allocate intermediate collections to represent the results. See the docs page (linked) for more.
input.view.map(_.toByte).toArray
Depending on how you intend to pass the resulting value around, you may not even need to call .toArray. For example if all you need to do is iterate the elements later on, you could just pass the view around as an Iterable[Byte] without ever having to allocate a separate array.
All the current answers require iterating over the array in user space.
Scala.js has optimizer supported conversions for typed arrays (in fact, Array[Byte] are typed arrays in modern configs). You'll likely get better performance by doing this:
import scala.scalajs.js.typedarray._
def toScalaArray(input: Uint8Array): Array[Byte] = {
// Create a view as Int8 on the same underlying data.
new Int8Array(input.buffer, input.byteOffset, input.length).toArray
}
The additional new Int8Array is necessary to re-interpret the underlying buffer as signed (the Byte type is signed). Only then, Scala.js will provide the built in conversion to Array[Byte].
When looking at the generated code, you'll see no user space loop is necessary: The built-in slice method is used to copy the TypedArray. This will almost certainly not be beatable in terms of performance by any user-space loop.
$c_Lhelloworld_HelloWorld$.prototype.toScalaArray__sjs_js_typedarray_Uint8Array__AB = (function(input) {
var array = new Int8Array(input.buffer, $uI(input.byteOffset), $uI(input.length));
return new $ac_B(array.slice())
});
If we compare this with the currently accepted answer (input.view.map(_.toByte).toArray) we see quite a difference (comments mine):
$c_Lhelloworld_HelloWorld$.prototype.toScalaArray__sjs_js_typedarray_Uint8Array__AB = (function(input) {
var this$2 = new $c_sjs_js_IterableOps(input);
var this$5 = new $c_sc_IterableLike$$anon$1(this$2);
// We need a function
var f = new $c_sjsr_AnonFunction1(((x$1$2) => {
var x$1 = $uS(x$1$2);
return ((x$1 << 24) >> 24)
}));
new $c_sc_IterableView$$anon$1();
// Here's the view: So indeed no intermediate allocations.
var this$8 = new $c_sc_IterableViewLike$$anon$6(this$5, f);
var len = $f_sc_TraversableOnce__size__I(this$8);
var result = new $ac_B(len);
// This function actually will traverse.
$f_sc_TraversableOnce__copyToArray__O__I__V(this$8, result, 0);
return result
});
import scala.scalajs.js
def toScalaArray(input: js.typedarray.Uint8Array): Array[Byte] =
input.toArray.map(_.toByte)

Scala drivers for couchdb and partial schemas

One question I have about current Scala couchdb drivers is whether they can work with "partial" schemas". I'll try to explain what I mean: the libraries I've see seem to all want to do a complete conversion from JSON docs in the database to a Scala object, handle the Scala object, and convert it back to JSON. This is is fine if your application knows everything about that type of object --- especially if it is the sole piece of software interacting with that database. However, what if I want to write a little application that only knows about part of the JSON object: for example, what if I'm only interested in a 'mybook' component embedded like this:
{
_id: "0ea56a7ec317138700743cdb740f555a",
_rev: "2-3e15c3acfc3936abf10ea4f84a0aeced",
type: "user",
profiles: {
mybook: {
key: "AGW45HWH",
secret: "g4juh43ui9hg929gk4"
},
.. 6 or 7 other profiles
},
.. lots of other stuff
}
I really don't want to convert the whole JSON AST to a Scala object. On the other hand, in couchdb, you must save back the entire JSON doc, so this needs to be preserved somehow. I think what I really what is something like this:
class MyBook {
private val userJson: JObject = ... // full JSON retrieved from the database
lazy val _id: String = ... // parsed from the JSON
lazy val _rev: String = ... // parsed from the JSON
lazy val key: String = ... // parsed from the JSON
lazy val secret: String = ... // (ditto)
def withSecret(secret: String): MyBook = ... // new object with altered userJson
def save(db: CouchDB) = ... // save userJson back to couchdb
}
Advantages:
computationally cheaper to extract only needed fields
don't have to sync with database evolution except for 'mybook' part
more suitable for development with partial schemas
safer, because there is less change as inadvertently deleting fields if we didn't keep up with the database schema
Disadavantages:
domain objects in Scala are not pristinely independent of couch/JSON
more memory use per object
Is this possible with any of the current Scala drivers? With either of scouchdb or the new Sohva library, it seems not.
As long as you have a good JSON library and a good HTTP client library, implementing a schemaless CouchDB client library is really easy.
Here is an example in Java: code, tests.
My couchDB library uses spray-json for (de)serialization, which is very flexible and would enable you to ignore parts of a document but still save it. Let's look at a simplified example:
Say we have a document like this
{
dontcare: {
...
},
important: "foo"
}
Then you could declare a class to hold information from this document and define how the conversion is done:
case class Dummy(js:JsValue)
case class PartialDoc(dontcare: Dummy, important: String)
implicit object DummyFormat extends JsonFormat[Dummy] {
override def read(js:JsValue):Dummy = Dummy(js)
override def write(d:Dummy):JsValue = d.js
}
implicit val productFormat = jsonFormat2(PartialDoc)
This will ignore anything in dontcare but still safe it as a raw JSON AST. Of course this example is not as complex as the one in your question, but it should give you an idea how to solve your problem.

scala game programming: advancing object position in a functional style

Long time java programmer slowly learning scala (loving it by the way), and I think my mind is still wrapping itself around the concept of writing things functionally. Right now I'm attempting to write a simple visualizer for some moving 2d textures. The imperative approach is simple enough, and I'm sure most of you will recognize this relatively ubiquitous block of code (stuff was changed to protect the innocent):
class MovingTexture(var position, var velocity) extends Renders with Advances {
def render : Unit = {...}
def advance(milliseconds : Float) : Unit = {
position = position + velocity * milliseconds
}
}
This code will work just fine, however it has tons of mutable state and its functions are replete with side effects. I can't let myself get away with this, there must be a better way!
Does anyone have an amazing, elegant, functional solution to this simple problem? Does anyone know of a source where I could learn more about solving these sorts of problems?
There's way more to this answer than can be fit in the space of one stackoverflow response, but the best and most complete answer to questions like this is to use something called Functional Reactive Programming. The basic idea is to represent each time-varying or interactive quantity not as a mutable variable, but rather as an immutable stream of values, one for each time quanta. The trick then is that while each value is a represented by a potentially infinite stream of values, the streams are lazily calculated (so that memory isn't taken up until needed), and stream values aren't looked at for time quanta in the past (so that the previous calculations may be garbage collected). The calculation is nicely functional and immutable, but the part of the calculation you are "looking at" changes with time.
This is all rather intricate, and combining streams like this is tricky, particularly if you wish to avoid memory leaks and have everything work in a thread-safe and efficient manner. There are a few Scala libraries that implement Functional Reactive Programming, but maturity isn't yet very high. The most interesting is probably scala.react, described here .
Games are often high-performance affairs, in which case you may find that mutable state is just the thing you need.
However, in this case, there are a couple of simple solutions:
case class MovingTexture(position: VecXY, velocity: VecXY) extends Renders with Advances {
def advance(ms: Float) = copy(position = position + ms*velocity
def accelerate(acc: Float, ms: Float) = copy(velocity = velocity + ms*acc)
...
}
That is, instead of having your classes update themselves, have them return new copies of themselves. (You can see how this could get expensive quickly. For Tetris, no big deal. For Crysis? Maybe not so smart.) This seems like it just pushes the problem back one level: now you need a var for the MovingTexture, right? Not at all:
Iterator.iterate(MovingTexture(home, defaultSpeed))(_.advance(defaultStep))
This will produce an endless stream of position updates in the same direction. You can do more complicated things to mix in user input or whatnot.
Alternatively, you can
class Origin extends Renders {
// All sorts of expensive stuff goes here
}
class Transposed(val ori: Origin, val position: VecXY) extends Renders with Advances {
// Wrap TextureAtOrigin with inexpensive methods to make it act like it's moved
def moving(vel: VecXY, ms: Float) = {
Iterator.iterate(this).(tt => new Transposed(tt.ori, position+ms*vel))
}
}
That is, have heavyweight things never be updated and have lighter-weight views of them that make them look as though they've changed in the way that you want them changed.
There's a brochure called "How to design worlds" (by the authors of "How to design programs") which goes into some length about a purely functional approach to programming interactive applications.
Basically, they introduce a "world" (a datatype that contains all the game state), and some functions, such as "tick" (of type world -> world) and "onkeypress" (of type key * world -> world). A "render" function then takes a world and returns a scene, which is then passed to the "real" renderer.
Here's a sample of some code I've been working on that uses the approach of returning a copy rather than mutating state directly. The nice thing about this kind of approach, on the server side at least, is that it enables me to easily implement transaction-type semantics. If something goes wrong while doing an update, it's trivial for me to still have everything that was updated in a consistent state.
The code below is from a game server I'm working on, which does something similar to what you're doing, it's for tracking objects that are moving around in time slices. This approach isn't as spectacular as what Dave Griffith suggests, but it may be of some use to you for contemplation.
case class PosController(
pos: Vector3 = Vector3.zero,
maxSpeed: Int = 90,
velocity: Vector3 = Vector3.zero,
target: Vector3 = Vector3.zero
) {
def moving = !velocity.isZero
def update(elapsed: Double) = {
if (!moving)
this
else {
val proposedMove = velocity * elapsed
// If we're about to overshoot, then stop at the exact position.
if (proposedMove.mag2 > pos.dist2(target))
copy(velocity = Vector3.zero, pos = target)
else
copy(pos = pos + proposedMove)
}
}
def setTarget(p: Vector3) = {
if (p == pos)
this
else {
// For now, go immediately to max velocity in the correct direction.
val direction = (p - pos).norm
val newVel = direction * maxSpeed
copy(velocity = direction * maxSpeed, target = p)
}
}
def setTargetRange(p: Vector3, range: Double) = {
val delta = p - pos
// Already in range?
if (delta.mag2 < range * range)
this
else {
// We're not in range. Select a spot on a line between them and us, at max range.
val d = delta.norm * range
setTarget(p - d)
}
}
def eta = if (!moving) 0.0 else pos.dist(target) / maxSpeed
}
One nice thing about case classes in Scala is that they create the copy() method for you-- you just pass in which parameters have changed, and the others retain the same value. You can code this by hand if you're not using case classes, but you need to remember to update the copy method whenever you change what values are present in the class.
Regarding resources, what really made a difference for me was spending some time doing things in Erlang, where there is basically no choice but to use immutable state. I have two Erlang books I worked through and studied every example carefully. That, plus forcing myself to get some things done in Erlang made me a lot more comfortable with working with immutable data.
This series of short articles helped me as a beginner, in thinking Functionally in solving programming problems. The game is Retro (Pac Man), but the programmer is not.
http://prog21.dadgum.com/23.html

Finite State Machine and inter-FSM signaling

Recommendations for languages with native (so no FSM generation tools) support for state machine development and execution and passing of messages/signals. This is for telecoms, e.g implementation of FSMs of this level of complexity.
I have considered Erlang, but would love some feedback, suggestions, pointer to tutorials, alternatives, particularly Java based frameworks. Maybe Scala?
Open source only. I'm not looking for UML or regular expression related solutions.
As this is for the implementation of telecoms protocols the FSMs may be non-trivial. Many states, many transitions, signal based, input constraints/guards. Dynamic instantiation would be a plus. Switch statements are out of the question, it quickly nests to unusable. It's barely better that if/else.
I would prefer to not depend on graphical design; the format FSM description should be human readable/editable/manageable.
--
I have decided to focus on an Actor based solution for C++
For example, the Theron framework provides a starting point http://theron.ashtonmason.net/ and to avoid switch statements in the FSM based event handler this C++ FSM Template Framework looks useful http://satsky.spb.ru/articles/fsm/fsmEng.php
This particular application, telco protocol implementation, is what Erlang was built for. The initial applications of Erlang at Ericsson were telephone switches and the earliest commercial products were ATM switches supporting all manner of telco protocols.
OTP has a standard behaviour for implementing FSMs called gen_fsm. There's an example of its use in a non-trivial FSM in some of the OTP Documentation.
OSERL is an open souce SMPP implementation in Erlang and demonstrates how you can implement a telco protocol using gen_fsms. A good example to look at would be gen_esme_session.
While I can't point you to the code, I know there are quite a few Erlang companies selling telco oriented products: Corelatus, Synapse, Motivity among others.
I agree that switch statements should be out of the question... they eventually lead to maintenance nightmares. Can't you use the State Pattern to implement your FSM? Depending on your actual implementation, you could use actors (if you have multiple FSM collaborating - hm... is that possible?). The nice thing about actors is that the framework for passing messages is already there.
An example of using State would be:
trait State {
def changeState(message: Any): State
}
trait FSM extends Actor {
var state: State
def processMessage(message: Any) {
state = state.changeState(message)
}
override def act() {
loop {
react {
case m: Any => processMessage(m)
}
}
}
}
This is very basic code, but as I don't know more of the requirements, that's the most I can think of. The advantage of State is that every state is self-contained in one class.
I disagree that FSM are trivial to implement. This is very short-sighted, and shows either a lack of familiarity with the alternatives, or the lack of experience with complex state machines.
The fundamental problem is that a state machine graph is obvious, but FSM code is not. Once you get beyond a dozen states and a score of transitions, FSM code becomes ugly and difficult to follow.
There are tools whereby you draw the state machine, and generate Java code for it. I don't know of any open source tools for that, however.
Now, getting back to Erlang/Scala, Scala has Actors and message passing as well, and is based on the JVM, so it might be a better alternative than Erlang given your constraints.
There's a DFA/NFA library on Scala as well, though it is not particularly a good one. It supports conversion from arbitrary regular expressions (ie, the literals need not be characters) into DFA/NFA.
I'll post some code below using it. In this code, the idea is creating a FSM which will accept any sequential combination of arbitrary prefixes for a list of words, the idea being looking up menu options without predefined keybinds.
import scala.util.regexp._
import scala.util.automata._
// The goal of this object below is to create a class, MyChar, which will
// be the domain of the tokens used for transitions in the DFA. They could
// be integers, enumerations or even a set of case classes and objects. For
// this particular code, it's just Char.
object MyLang extends WordExp {
type _regexpT = RegExp
type _labelT = MyChar
case class MyChar(c:Char) extends Label
}
// We now need to import the types we defined, as well as any classes we
// created extending Label.
import MyLang._
// We also need an instance (singleton, in this case) of WordBerrySethi,
// which will convert the regular expression into an automatum. Notice the
// language being used is MyLang.
object MyBerrySethi extends WordBerrySethi {
override val lang = MyLang
}
// Last, a function which takes an input in the language we defined,
// and traverses the DFA, returning whether we are at a sink state or
// not. For other uses it will probably make more sense to test against
// both sink states and final states.
def matchDet(pat: DetWordAutom[MyChar], seq: Seq[Char]): Boolean =
!pat.isSink((0 /: seq) ((state, c) => pat.next(state, MyChar(c))))
// This converts a regular expression to a DFA, with using an intermediary NFA
def compile(pat: MyLang._regexpT) =
new SubsetConstruction(MyBerrySethi.automatonFrom(pat, 100000)).determinize
// Defines a "?" function, since it isn't provided by the library
def Quest(rs: _regexpT*) = Alt(Eps, Sequ(rs: _*)) // Quest(pat) = Eps|pat = (pat)?
// And now, the algorithm proper. It splits the string into words
// converts each character into Letter[MyChar[Char]],
// produce the regular expression desired for each word using Quest and Sequ,
// then the final regular expression by using Sequ with each subexpression.
def words(s : String) = s.split("\\W+")
def wordToRegex(w : String) : Seq[MyLang._regexpT] = w.map(c => Letter(MyChar(c)))
def wordRegex(w : String) = Quest(wordToRegex(w) reduceRight ((a,b) => Sequ(a, Quest(b))))
def phraseRegex(s : String) = Sequ(words(s).map(w => wordRegex(w)) : _*)
// This takes a list of strings, produce a DFA for each, and returns a list of
// of tuples formed by DFA and string.
def regexList(l : List[String]) = l.map(s => compile(phraseRegex(s)) -> s)
// The main function takes a list of strings, and returns a function that will
// traverse each DFA, and return all strings associated with DFAs that did not
// end up in a sink state.
def regexSearcher(l : List[String]) = {
val r = regexList(l)
(s : String) => r.filter(t => matchDet(t._1, s)).map(_._2)
}
I can hardly think of any language where implementing an FSM is non-trivial. Maybe this one.
...
if (currentState == STATE0 && event == EVENT0) return STATE1;
if (currentState == STATE1 && event == EVENT0) return STATE2;
...
The State pattern (using Java enums) is what we use in our telecom application, however we use small FSM's:
public class Controller{
private State itsState = State.IDLE;
public void setState(State aState){
itsState = aState;
}
public void action1(){
itsState.action1(this);
}
public void action2(){
itsState.action2(this);
}
public void doAction1(){
// code
}
public void doAction2(){
// code
}
}
public enum State{
IDLE{
#Override
public void action1(Controller aCtx){
aCtx.doAction1();
aCtx.setState(State.STATE1);
}
},
STATE1{
#Override
public void action2(Controller aCtx){
aCtx.doAction2();
aCtx.setState(State.IDLE);
}
},
public void action1(Controller aCtx){
throw new IllegalStateException();
}
public void action2(Controller aCtx){
throw new IllegalStateException();
}
}
FSM should be trivial to implement in any language that has a case statement.Your choice of language should be based on what that finite state machine needs to do.
For example, you state that you need to do this for telecom development and mention messages. I would look at systems/languages that support distributed message passing. Erlang does this, and I"m sure just about every other common language supports this through an API/library for the language.

GWT: How to avoiding calls to dynamicCast and canCastUnsafe in generated JavaScript code?

I'm writing some special purpose data structures in Java, intended for use in the browser, (compiled to JavaScript with GWT).
I'm trying to match the performance of some of the built-in JDK classes I'm noticing things run reasonably fast, but when I compare my code trace to some of the emulated JDK code, mine has lots of calls to dynamicCast and canCastUnsafe, while the JDK emulated classes do not. And it just about accounts for the difference in performance too...
Any GWT gurus out there know how to avoid this? It's amounting to a 20% overhead :-(
Details:
Here's the profile output (captured in Firebug) for 10,000 insertions of random integers, between 0 and 100,000 into two different data structures:
Google's TreeMap implementation for java.util.TreeMap (a red-black tree):
Profile (4058.602ms, 687545 calls)
Function Calls Percent Own Time
$insert_1 129809 41.87% 1699.367ms
$compare_0 120290 16% 649.209ms
$isRed 231166 13.33% 540.838ms
compareTo_0 120290 8.96% 363.531ms
$put_2 10000 6.02% 244.493ms
wrapArray 10000 3.46% 140.478ms
createFromSeed 10000 2.91% 118.038ms
$TreeMap$Node 10000 2.38% 96.706ms
initDim 10000 1.92% 77.735ms
initValues 10000 1.49% 60.319ms
$rotateSingle 5990 0.73% 29.55ms
TreeMap$Node 10000 0.47% 18.92ms
My Code (An AVL tree):
Profile (5397.686ms, 898603 calls)
Function Calls Percent Own Time
$insert 120899 25.06% 1352.827ms
$compare 120899 17.94% 968.17ms
dynamicCast 120899 14.12% 762.307ms <--------
$balanceTree 120418 13.64% 736.096ms
$setHeight 126764 8.93% 482.018ms
compareTo_0 120899 7.76% 418.716ms
canCastUnsafe 120899 6.99% 377.518ms <--------
$put 10000 2.59% 139.936ms
$AVLTreeMap$Node 9519 1.04% 56.403ms
$moveLeft 2367 0.36% 19.602ms
AVLTreeMap$State 9999 0.36% 19.429ms
$moveRight 2378 0.34% 18.295ms
AVLTreeMap$Node 9519 0.34% 18.252ms
$swingRight 1605 0.26% 14.261ms
$swingLeft 1539 0.26% 13.856ms
Additional observations:
Same problem for another data structure I made (SkipList).
dynamicCast is being applied in the compare function:
cmp = dynamicCast(right.key, 4).compareTo$(key);
dynamicCast goes away if the class does not implement Map (ie: just removing " implements Map" from the class. Doesn't matter if it's accessed through the interface or directly. This results in the same line compiling to:
cmp = right.key.compareTo$(key);
This is the relevant section of Java source from SkipList:
private int compare(Node a, Object o) {
if (comparator != null)
return comparator.compare((K) a.key, (K) o);
return ((Comparable<K>) a.key).compareTo((K) o);
}
public V get(Object k) {
K key = (K) k;
Node<K, V> current = head;
for (int i = head.height - 1; i >= 0; i--) {
Node<K, V> right;
while ((right = current.right[i]) != null) {
int cmp = compare(right, key);
...
}
}
}
Unfortunately I'm still not exactly clear on the cause, but from my experience, it seems from explicit casts, like:
((Comparable) obj).compareTo(other)
The Javascript generated looks like:
dynamicCast(obj, 1).compareTo(other);
Where 1 is a generated typeId representing the target of the cast. dynamicCast in turn calls canCastUnsafe and if false, it throws a ClassCastException. The value of this has been debated, since this would already be caught in hosted mode.
It can be sidestepped with JSNI:
public static native int compare(Object a, Object b) /*-{
return a.#java.lang.Comparable::compareTo(Ljava/lang/Object;)(b);
}-*/;
Dunno if you've seen this thread in the GWT Contributor's forum...
Basically, it starts with the same problem you've identified, proposes some new compiler flags, and goes on to show how to use some JSNI to get around the casts.
Edit In the GWT trunk there's a new compiler flag. See the wiki...
An updated answer for GWT version 2.1 and later:
Since GWT 2.1 (at least that's the first mention), the GWT compiler has a new compiler argument called -XdisableCastChecking that disables all runtime checking of casts.
Note, this option is marked as experimental (probably because this would make class cast exceptions very hard to debug).
In my app dynamicCast was called thousands of times in a short profile run, and were the the 3rd most time consuming method in the Firebug profiler. Using this compiler argument significantly reduced the number of "Long Duration Events" messages in the Chrome Speed Tracer.
See GWT Compiler Options for this and other Compiler arguments.
It's definitely a compiler problem: I have the problem on the following line:
final DefaultIconedSuggestBox<SuggestValueProxy, IconedValueHolderItem<SuggestValueProxy>> fieldValueWidget = getCategoryWidget().getFieldValueWidget();
I don't really know how I can workaround it: this line happens in a moment I'm changing from a module to another (it is maybe related to the code splitter issue: even though I'm not using code split: I'm just loading another page with another module)
Does the use of java 1.5 generics and wildcards could avoid this ?