Are there any other sources of performance related material?
I'm going to be working on profiling/tweaking my app and would like to
have some solid leads for things to look at.
Thank you,
Donald
* Never do something like implicit def f(x) = new { ... }; instead,
create a class, and do new XXX.
* In fact, be sure implicit conversions are not doing something
unexpected. For example, "abc".size is much slower than "abc".length.
For this reason, avoid JavaConversions and use JavaConverters instead.
* List has very particular performance characteristics. Use it only if
you understand them well. Otherwise, play it safe and use Vector --
it's often better anyway. You should learn the performance
characteristics of the collections anyway -- they are documented
somewhere on docs.scala-lang.org.
* There are trade offs between immutable and mutable collections --
understand them and pick the right collection.
* Chaining multiple operations may lead to cache misses due to
excessive object allocation. In such cases, converting first to
Iterator and then back to the expected collection at the end can
improve performance significantly. In many cases, you don't even need
to convert back to a collection.
* Avoid structural types. By the way, doing "val x = new XXX { .... }"
leads to structural types. Doing "val x: XXX = new XXX { ... }" in
these cases avoid them.
These are cheap tips. Real performance needs two things:
1. Measurements. Use a library that collect timing statistics and
sprinkle calls to it along the processing pipelines of your code.
2. Profiling. Use tools to gather data about what the application is doing.
These two are related, but the former will miss everything you miss,
and may not tell you _why_ something is slow. On the other hand, it
can, and should, be performed on production as well. The latter can
find things you missed or did not know about, but often results in
serious performance degradation.
--
Daniel C. Sobral
I travel to the future all the time.
* Avoid structural types. By the way, doing "val x = new XXX { .... }"
leads to structural types. Doing "val x: XXX = new XXX { ... }" in
these cases avoid them.
If you are dealing with a lot of primitives (e.g. huge arrays of
Doubles or Ints) you may want to avoid situations which will cause each
element to be boxed/unboxed when accessed/stored. Right now in 2.9 that
means that you may want to try to store these in Array[Int] rather than
List[Int] or Vector[Int] (Currently Array is the only collection that
doesn't cause boxing of primitives).
Similarly, if you find yourself operating on millions of values, you
may want to start paying attention to how many objects you create,
since at this point the allocation/gc overhead may start to be a
problem. One example of this would be to represent an array of points
as an array of X coordinates and an array of Y coordinates (rather than
an array of tuples) to avoid allocating the extra objects.
Finally, there are a class of situations involving collections and
loops where using higher-level constructs will impose a penalty. For
instance, while loops are currently still faster than foreach/for in
Scala (although hopefully not for long). It's hard to enumerate these,
but you can discover them through testing (and reading the source in
some cases).
In general I don't think these things are a problem for most people,
but they do come up.
-- Erik
Probably not -- I'd check with javap to make sure, though. The problem
happens when you add something that is not an override, and that leads
to structural types.
Am 13.04.2012 22:19, schrieb Rex Kerr:really? i always assumed it would only be a structural type if i add a method, for example:On Fri, Apr 13, 2012 at 4:01 PM, Daniel Sobral <dcso...@gmail.com> wrote:
* Avoid structural types. By the way, doing "val x = new XXX { .... }"
leads to structural types. Doing "val x: XXX = new XXX { ... }" in
these cases avoid them.
This is #1 on my list of poorly designed Scala features (as opposed to sensibly designed but still buggy features, or lack-of-feature-that-I-wish-was-there). Scala does the wrong thing ~99% of the time. (In my code, as a Bayesian estimate.)
I hope that these will someday _not_ be structural types and all the "don't do that" advice will, thankfully, become irrelevant.
--Rex
Those were the words I was searching for. :-)
When doing anything nontrivial, it's really easy to add a method and not
mark it private.
Ok, but I expected that only the "strcutural methods" (that is, all the non inherited one) are dispatched via reflection, so if I extend something and add a non private method for example, still, if I only use that instance by its parent definition, then there should be no performance penalty right? after all, those methods need not use reflection.. right?When doing anything nontrivial, it's really easy to add a method and not
mark it private.