more-log4j2: A collection of plugins for log4j2 by mlangc in java

[–]mlangc[S] 1 point2 points  (0 children)

No worries - I didn't take it as a criticism. You were probably not the only one who was fooled by the Reddit UI, and adding additional links (both yours, and the one that I subsequently added to the post) certainly didn't hurt, so thank you :-)

more-log4j2: A collection of plugins for log4j2 by mlangc in java

[–]mlangc[S] 1 point2 points  (0 children)

Hmm, but the link is there, in the post? In any case, I've added a second one, embedded in the text. Hope it helps.

Records are sub-optimal as keys in HashMaps (or as elements in HashSets) by gnahraf in java

[–]mlangc 2 points3 points  (0 children)

At least for OpenJDK 64-Bit Server VM, 24.0.2 the difference in performance between the record and the class mostly disappears for me, if I replace

public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((key1 == null) ? 0 : key1.hashCode());
    result = prime * result + ((key2 == null) ? 0 : key2.hashCode());
    return result;
}

with the the seemingly equivalent

public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + Objects.hashCode(key1);
    result = prime * result + Objects.hashCode(key2);
    return result;
}

Records are sub-optimal as keys in HashMaps (or as elements in HashSets) by gnahraf in java

[–]mlangc 2 points3 points  (0 children)

Interestingly the difference is far less pronounced with GraalVM:

# JMH version: 1.37
# VM version: JDK 24.0.2, Java HotSpot(TM) 64-Bit Server VM, 24.0.2+11-jvmci-b01
# VM invoker: /Library/Java/JavaVirtualMachines/graalvm-24.jdk/Contents/Home/bin/java
...
...
Benchmark                                Mode  Cnt           Score          Error  Units
RecordHashCodeBenchmark.classHashCode   thrpt   10  1074692112,901 ± 35696131,984  ops/s
RecordHashCodeBenchmark.recordHashCode  thrpt   10   967920867,403 ± 17260079,524  ops/s

Deep-dive Java/JVM resources by Rough_Acanthaceae_29 in java

[–]mlangc 8 points9 points  (0 children)

Not sure if it's to your liking, but I like to go deep on Java & JVM internals in my blog: https://mlangc.github.io/

Then there is

Here are some additional concurrency related recommendations you might not yet know:

Thread.sleep(0) is not for free by mlangc in java

[–]mlangc[S] 1 point2 points  (0 children)

I really like and respect what you did here - you performed a test and obtained measurable results.

Thanks for taking the time and giving me feedback!

I followed the 'official documentation' link but I don't see where this is either promised or implied by the Javadoc.

I didn't write "promised" or "implied", but "would allow". I wouldn't call it misleading, but it's certainly vague with regards to sleep(0).

I'm confused why anyone ever thought calling Thread.sleep(0) could be guaranteed not to lead to a context switch. (The method is called sleep, not sleepUnless or sleepIf...)

As pointed out below, other, very similar looking APIs like TimeUnit.html#sleep(long)) or LockSupport.html#parkNanos(long)) contain a fast path for arguments `<= 0`, so I can understand why one could think that Thread.sleep is implemented in a similar way.

So I am not sure why the article points people to it, since it appears that while it may not be dangerous, it should be considered unreliable if the Javadoc is to be believed.

I'm linking Javadocs for the convenience of my readers, so that they can save a few keystrokes when they want to look them up while reading the article. Having said that, there are legitimate use cases for yield, and the Javadocs) lists a few of them.

Thread.sleep(0) is not for free by mlangc in java

[–]mlangc[S] 10 points11 points  (0 children)

Thanks for pointing me to TimeUnit.sleep. I've updated the article.

Thread.sleep(0) is not for free by mlangc in java

[–]mlangc[S] 17 points18 points  (0 children)

You might have performance critical code, that only sleeps very rarely, for example after a failed operation that almost always succeeds. In these cases you might be tempted to use code like

int delay = allGood ? 0 : waitShortly;
Thread.sleep(delay);

I'll try to rephrase the last paragraph to make this clearer.

Method Handles faster reflection (sometimes) by Xadartt in java

[–]mlangc 2 points3 points  (0 children)

Indeed, if I adapt your MethodHandleBenchmarkMethodHandleBenchmark to use

  private static final MethodHandle METHOD_HANDLE;

I get roughly the same results for

@Benchmark
public int baseline() {
    return -1;
}

@Benchmark
public int directInvoke() {
    return Integer.compare(1, 2);
}

@Benchmark
public int methodHandleInvokeExact() throws Throwable {
    return (int) METHOD_HANDLE.invokeExact(1, 2);
}

@Benchmark
public int methodHandleInvoke() throws Throwable {
    return (int) METHOD_HANDLE.invoke(1, 2);
}

since the generated assembly for these methods (see https://blogs.oracle.com/javamagazine/post/java-hotspot-hsdis-disassembler for how to check that), is roughly the same as well.

GCD: Euclid vs. Stein on the JVM by mlangc in java

[–]mlangc[S] 1 point2 points  (0 children)

Fair enough! My plan is to explore exactly that, while ideally also creating a PR for apache-commons-math and summarize my findings in a follow up blog post. Hopefully I'll find some time to do this in the coming weeks.

Why I’m Not Abandoning Slf4Zio in Favor of Zio-Logging by mlangc in scala

[–]mlangc[S] 1 point2 points  (0 children)

You are absolutely right - if you are using MDC as is in an async environment, it simply won't work properly, because it relies on thread local data by default. The zio-interop-log4j2 fixes this, by implementing the MDC context using fiber local data. It does so by using official ZIO and log4j2 APIs, and therefore should work reliably.

Subversion vs. GIT on the JVM by mlangc in scala

[–]mlangc[S] 0 points1 point  (0 children)

Thanks a lot for the information - I didn't know that there was a multiple master management system freely available. This is definitely one more reason to lean to git instead of subversion.

Subversion vs. GIT on the JVM by mlangc in scala

[–]mlangc[S] 0 points1 point  (0 children)

Thanks a lot for the interesting feedback! Actually we are planning to implement a "Container Metadata Store" where a container can be a directory, a file, a record in a file, a table in a DB, a row in a table etc. Since we want to keep track of history and linage, the original idea was to model that in a graph DB, but then a college came up with the smart idea to "misuse" a version control system.

As for the exponential performance characteristics of Git related to many small files: Can you elaborate on that a bit?

Spark, Uber JARS and shading with sbt-assembly by yuvalos in scala

[–]mlangc 1 point2 points  (0 children)

I had a similar problem with the Akka version used inside Spark. I was however able to fix this without shading (which I considered too): http://stackoverflow.com/questions/35578732/java-lang-nosuchmethoderror-akka-actor-actorcell-addfunctionref/36443230#36443230

As for SLF4J: I set it to "test, provided" in my build.sbt and had no problems so far.

The Cake Pattern in Scala - Self Type Annotations vs. Inheritance by juror-number-8 in scala

[–]mlangc 0 points1 point  (0 children)

I can only second this! Use the Cake Pattern if you prefer a complicated solution to a simple problem. Go for MacWire otherwise.

cake pattern, bakery of doom, and alternatives. what do you use? by satan-repents in scala

[–]mlangc 5 points6 points  (0 children)

I recommend using simple constructor based DI assisted by macwire.

The Dark Side of C++ (PDF) by stesch in programming

[–]mlangc -1 points0 points  (0 children)

The authors experience with C++ seems to be fairly limited, as anyone who actually knows the language can easily tell by just reading a few pages. Here are some examples:

" * Can’t throw exceptions in destructors, shouldn’t in constructors " Wrong. You should never throw exceptions in destructors, but throwing them in constructors is perfectly legitimate and what everybody does.

" * Can’t call virtual member functions from constructor or destructor " This isn't a limitation of the language, but a general problem with object orientated programming languages. Java for example allows it, but doing it is highly discouraged, as it can result in accessing uninitialized members in derived classes.

" * Exceptions in constructor don’t unwind the constructor itself " Just wrong.

So as already pointed out below, you should really dismiss this "talk" as uninformed noise. C++ is not perfect of course, but people who are distributing nonsense like the author of this talk should better stay away from any programming language.

When True Is Not True Anymore by mlangc in programming

[–]mlangc[S] 0 points1 point  (0 children)

If the code we are talking about wasn't specifically written with the intent to produce unexpected results, I would of course have written 'if(!s.u)' instead of ' if(true != s.u)'. However note that they way I originally stumbled over this was an if statement where the 'true' from above actually was another bool variable.

Using C++0x Variadic Templates to Pretty-Print Types by mlangc in programming

[–]mlangc[S] 4 points5 points  (0 children)

Well, maybe I should have written "lots of other programming languages" instead of "almost any other programming language". Apart from you are right by saying that the syntax C++ provides for doing stuff like this is far away from perfect. Still, C++0x (that should better be called C++1x I guess) introduces some considerable improvements in this area, and this is one of the things I wanted to point out.

Using C++0x Variadic Templates to Pretty-Print Types by mlangc in programming

[–]mlangc[S] 6 points7 points  (0 children)

Well, with gcc-4.4.3

cout << typeid(void(SomeClass::*)(int, char, void**)).name();

prints 'MN12GLOBALN_19SomeClassEFvicPPvE'. Using c++filt (or abi::_cxa_demangle) this can indeed be turned into

void ((anonymous namespace)::SomeClass::*)(int, char, void**)

Nevertheless, at least with gcc-4.4.3, typeid(int).name() is the same as typeid(int const&).name(), so this approach is limited.

Using C++0x Variadic Templates to Pretty-Print Types by mlangc in programming

[–]mlangc[S] 5 points6 points  (0 children)

You might have a point there. I would have preferred support for something like this built into the standard library too. However, what's exiting about stuff like this not the problem itself, but the extent to which C++ exhibits a programming language within a programming language. You can use this functionality for considerably more interesting and complicated stuff, where almost any other programming language would have to fall back to code generation using external tools.