Hi, is there any way I can optimize this java code...
# getting-started
a
Hi, is there any way I can optimize this java code in Kotlin to have a something in one line ? I can't find anything right now, and I almost sure I have to do something with
.let
or similar functions but I can't come up with something
j
You could do:
Copy code
private fun enableAction() = (!action).also { action = true }
a
oh this is sweet, thanks !
e
if you're on JVM, you could use
Copy code
val action = AtomicBoolean()
fun enableAction() = !action.getAndSet(true)
kotlinx.atomicfu can do similar for common code as well
j
True, although
AtomicBoolean
is thread-safe, so this might incur a performance penalty
But I have to admit the readability is somewhat improved with AtomicBoolean
e
yes, atomic causes this operation to turn into a cross-thread synchronization point. whether that's desirable or too costly is a decision to be made in context
­čĹŹ 1
t
@ephemient Not exactly... this is atomic operation, that on x86 architecture doesn't imply synchronization. Those operation actually have dedicated processor instruction and if I am not mistaken are efficiently actually executed on memory bus. There are not semaphores or mutexes involved.
I read a little online. They imply memory bus lock, so I guess only one thread at a time can execute atomic operation and no other thread can fetch new cache line to L2 cache at that time.
So my conclusion would be - don't use atomics if you don't need to, as they are not just different syntax.
e
@Tomasz Krakowiak on JVM, atomic and volatile operations imply a full memory read or write barrier. on K/N, the memory model is in flux, but the intent is to match JVM. https://youtrack.jetbrains.com/issue/KT-43133 on K/JS, no threads so atomic is nop
t
@ephemient I knew volatile do, but I didn't know atomics do as well, but confirmed it in documentation. However, it's worth to mention, they do not imply themselves "cross-thread synchronization point". (depends on platform)
The specifications of these methods enable implementations to employ efficient machine-level atomic instructions that are available on contemporary processors. However on some platforms, support may entail some form of internal locking. Thus the methods are not strictly guaranteed to be non-blocking -- a thread may block transiently before performing the operation.
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html And there's also exclusion from volatile semantics for
weakCompareAndSet
weakCompareAndSet
 atomically reads and conditionally writes a variable but does not create any happens-before orderings, so provides no guarantees with respect to previous or subsequent reads and writes of any variables other than the target of the 
weakCompareAndSet
.
m
@Joffrey your first answer is so good but i saw this syntax first time why code is acting like this? we did not use == or != anywhere is it just looking for random two booleans in code and when it finds it understands it is comparing two booleans it did not really make sense for me can you explain sir?
j
Sure I can explain. The code in the question does 2 things: 1) sets
action
to true, 2) returns true if
action
has changed (because it stores the old value and compares with the new). So effectively, since
action
is always true in the end, it only changes when it was initially false. So if we forget about setting action to true, we need to return
!action
. Using
also
allows to perform extra actions without changing the value of the expression, so I used that to set action to true after calculating the expression
!action
(so it doesn't affect the result)
m
@Joffrey thank you so much i get it returning value is just first part and it is !action and we used also because after return any code will be useless but i learned we can use scope functions to do something after returning value,too and thanks to you i learned another advantage of scope functions.Thank you so much for your good answer.