Skip to content

Instantly share code, notes, and snippets.

View darichey's full-sized avatar

David Richey darichey

View GitHub Profile
@darichey
darichey / Content.md
Created January 27, 2019 23:19
String concat performance

String concatenation performance is a funny thing. Java 6-8, all string concat will be done with a StringBuilder. However, what we're actually concerned with is string concatenation in a loop. This is where the compiler does not make an optimization. A new StringBuilder will be allocated and used to concatenate to the String for every iteration of the loop. Because of this, for Java 8 and below, the definite advice is to change to a StringBuilder manually when doing concatenation in a loop.

Here's where things get interesting though. As of Java 9, javac no longer straight up converts to StringBuilder for all string concatenations. Instead, it uses invokedynamic. This means that at runtime many different strategies for concatenation can be chosen for code generation (one of which is still StringBuilder, for example). Because of this, the advice isn't so straight forward. As of today, manually converting to StringBuilder (as was done in the past) will likely yield better performance. However, the use of

@darichey
darichey / Content.md
Last active March 22, 2019 00:35
Variance

The reason you get Object when you use andThen with Consumer<? super EmbedCreateSpec> is because ? super EmbedCreateSpec indicates contravariance. Variance affects the subtyping relationship between types depending on the subtyping relathionship of their type parameters. You've probably seen ? extends which indicates covariance. I think this one is a bit easier to explain, so we'll do that and then go back to contravariance.

Covariance "forwards" the subtyping relationship to the containing type. That is, if T is a subtype of U (notated as T <: U) then List<T> is a subtype of List <? extends U>. For example, List<Double> is a subtype of List<? extends Number>. This is a useful relationship if we are only reading (that is, get()) from the list. We can never write (that is add() to this list). The following example helps show why:

List<? extends Number> list;
list = new ArrayList<Double>();
// list = new ArrayList<Long>();
@darichey
darichey / Content.md
Created January 27, 2019 22:54
SAM vs real function types and lambda type inference

SAM = Single Abstract Method. It's just another way of saying FunctionalInterface (technically the latter is more correct too because an abstract class with a single abstract method doesnt qualify for a SAM type). So in Java instead of having T -> () we have Consumer<T>. But nothing prevents me from writing an equivalent type:

interface MyDifferentConsumer<T> {
  void consume(T t);
}

This also represents T-> (), it just has a different name. I think the best place we can see how this affects inference is with method references. In java, both of these are perfectly valid:

Consumer<String> c1 = System.out::println;
MyDifferentConsumer c2 = System.out::println;
@darichey
darichey / notes.txt
Created December 16, 2018 19:33
Audio Notes
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+---+-+-+-------+---------------+-----------------------------+
|V |P|X| CSRC |M|Payload type | Sequence |
+---+-+-+-------+---------------+-----------------------------+
| Timestamp |
+-------------------------------------------------------------+
| SSRC |
+-------------------------------------------------------------+
| Audio Data ... |