Constant variable initialization based on IO operation with a condition - opencv

I've been programming some opencv app with kotlin and stumbled on a matter that I'm curious about based on the code below:
val image =
if (!Imgcodecs.imread(filename).empty())
Imgcodecs.imread(filename)
else
Mat.eye(512, 512, CvType.CV_8U).mul(Mat(512, 512, CvType.CV_8U, Scalar(255.0)))
Does compiler (in general) optimize such IO operations like these consecutive calls (imreads)?
What are the proven and / or elegant ways to deal with such problem?

I don't think the compiler has any way to know that an arbitrary method is side-effect free. And in fact this one isn't (I assume) - there's potential for a race condition here.
One way to avoid this is with something like this:
val image = with(Imgcodecs.imread(filename)) {
if (!empty()) {
this
} else {
Mat.eye(...)
}
}
Or something a bit more explicit, thus avoiding the magic of the with idiom:
val image = {
val mtx = Imgcodecs.imread(filename)
if (!mtx.empty()) {
mtx
} else {
Mat.eye(...)
}
}

Related

How do I iterate over a HashSet while simultaneously updating it in Rust?

In most languages, iterating over a container while simultaneously mutating it is a glaring anti-pattern. In Rust, the borrow checker makes it impossible.
But there are cases where this is needed. An example is Earley's algorithm for parsing. I'm new to Rust and I'm not aware of a known good way to iterate over a HashSet (or in fact any container) while extending it. I came up with the following (generalized from the Earley use case):
use std::collections::HashSet;
fn extend_from_within<T, F>(original: &mut HashSet<T>, process: F)
where T: std::cmp::Eq,
T: std::hash::Hash,
F: Fn(&T) -> Set<T>
{
let mut curr : HashSet<T> = HashSet::new(); // Items currently being processed
let mut next : HashSet<T> = HashSet::new(); // New items
// go over the original set once
let hack : &HashSet<T> = original; // &mut HashSet is not an iterator
for x in hack {
for y in process(x) {
if !original.contains(&y) {
curr.insert(y);
}
}
}
// Process and extend until no new items emerge
while !curr.is_empty() {
for x in &curr {
for y in process(x) {
// make sure that no item is processed twice
// the check on original is redundant, but might save space
if !curr.contains(&y) && !original.contains(&y) {
next.insert(y);
}
}
}
original.extend(curr.drain());
std::mem::swap(&mut curr, &mut next);
}
}
As you see, any call to process can yield multiple items. They are all added to the set and all of them have to be processed as well, but only if they haven't been seen. This works well enough. But keeping up to 4 sets, doing 3 checks for membership on each item (one of them twice on the original array) seems ridiculous for this problem. Is there a better way?
I'm not aware of a known good way to iterate over a HashSet (or in fact any Container) while extending it
I think there's mostly three patterns for handling modifications while iterating over HashMaps/HashSets:
Collecting the modifications into a Vec and applying them after the iteration
draining the HashSet and collecting into a new one
retain, but that's for deletions only
But your case is special anyway, you want to saturate your set with process, right?
Is there a better way?
In this case, I might go for
let mut todo = original.iter().map(Clone::clone).collect::<VecDeque<T>>();
while let Some(x) = todo.pop_front() {
for x in process(&x) {
if original.insert(x.clone()) {
todo.push_back(x);
}
}
}
The VecDeque is probably not necessary (a normal Vec would do), unless you have some requirement on the order of processing elements. Cache-wise, a Vec may be better.
One could avoid the clones by instead keeping the Set result of process(x) in todo. Without knowing what Set and T are, I can't say which is better. If the result of process is often empty, this would also allow to filter out empties before pushing them onto todo.
[Edit:] Another variant may be to
let mut todo = original
.iter()
.flat_map(&process)
.filter(|x| !original.contains(x))
.collect::<VecDeque<T>>();
todo.iter().for_each(|x| {
original.insert(x.clone());
});
// while let …
This might allocate less, but cause more hash map accesses / cache misses. Finding which variant is more efficient really requires benchmarking.

How does Vala handle reference counting with multithreading?

As far as I understand, in multithreaded environment reference counting should be performed with locking to ensure all threads see the same snapshot of memory. But locking slows down perfomance. How does Vala solve this problem?
Reference counting is mostly handled in GObject (for GLib.Object-derived types), which in turn uses the Atomic Operations in GLib. Atomics are a tricky subject; if you want to get into details a good place to start is Herb Sutter's Atomic Weapons talk from a few years ago. I would recommend watching the videos even if you're never going to put them to use (and 99.9% of programmers should never put them to use) because it will give you a much better understanding of how computers really work.
The name "atomics" can be a bit misleading; it's not really about atomicicity, though that's part of it. The operations are atomic in the sense that the change is either made in its entirety or not at all, which is vital, but the more interesting part is that atomics act as barriers which prevent the compiler from re-ordering operations across the barrier. Herb Sutter's talk goes into a lot of detail about this which I'm not going to repeat here.
For example, think about a simple unprotected reference counter:
typedef struct {
int reference_count = 0;
} Foo;
Foo* foo_create(void) {
Foo* foo = malloc(sizeof(Foo));
foo->reference_count = 1;
}
void ref(Foo* foo) {
++(foo->reference_count);
}
void unref(Foo* foo) {
if (--(foo->reference_count) == 0) {
free(foo);
}
}
I'm going to assume you can see the problems with leaving this unprotected because I'm writing a SO post not a book.
The specific atomic operation we're interested in is compare-and-swap (CAS), which basically provides the ability to perform this operation safely:
bool cas(int* value, int* expected, int desired) {
if (*value == *expected) {
*value = desired;
return true;
} else {
return false;
}
}
Using this, we would change our refcounting implementation above to something like:
typedef struct {
int reference_count = 0;
} Foo;
Foo* foo_create(void) {
Foo* foo = malloc(sizeof(Foo));
/* No atomics needed, we haven't made the value public yet */
foo->reference_count = 1;
}
void ref(Foo* foo) {
int old_refcount;
int new_refcount;
do {
current_refcount = foo->reference_count;
new_refcount = current_refcount + 1;
} while (!cas (&(foo->reference_count), &old_refcount, new_refcount))
}
void unref(Foo* foo) {
int old_refcount;
int new_refcount;
do {
current_refcount = foo->reference_count;
new_refcount = current_refcount - 1;
} while (!cas (&(foo->reference_count), &old_refcount, new_refcount));
if (new_refcount == 0) {
free(foo);
} else if (new_recount < 0) {
// Double-free bug, code should not be reached!
}
}
But locking slows down perfomance.
So do atomics. A lot. But also a lot less than a higher-level lock would. For one thing, if you were working with a mutex what you are doing would basically be:
Acquire the lock.
Perform the operation.
Release the lock.
With atomics, we're basically begging forgiveness instead of asking permission:
Attempt to perform the operation.
Then we just look to see whether the operation was successful (i.e., if cas() returned true).
The operation is also a lot smaller and faster; with a mutext, you would probably acquire the lock then read the current value, increment / decrement it, then release the lock. With atomics, the CAS operation gets wrapped up in a single CPU instruction.
The CPU still has to deal with cache coherency by making sure that next time any other core (a bit oversimplified since even within a core there are multiple caches) asks to read the data they are presented with the new data. In other words, atomic reference counting is bad for performance, but it's a lot less bad than a mutex. Frankly, if you want reference counting instead of tracing garbage collection atomics are pretty much your least-bad option.

Return/break out of infinite foreach in kotlin

For class I have to make a program that calculates the birthday problem
Now I'm having trying to learn kotlin at the same time and I'm having trouble with a little snippet of code:
val checkSet = mutableSetOf<Int>()
generateSequence{ Random.nextInt(n)}.forEach {
if(!checkSet.add(it)) {
return#outForeach
}
}
outForeach#
sum += checkSet.size
As you can see I'm trying to do this with an infinite sequence. Kotlin doesn't accept this as outForeach is an unresolved reference. But this doesn't work either:
val checkSet = mutableSetOf<Int>()
generateSequence{ Random.nextInt(n)}.forEach {
if(!checkSet.add(it)) {
return#forEach
}
}
sum += checkSet.size
This will just start the forEach loop again. Is there a way to implement something as a forEachUntil or so?
p.s. I'm aware that this looks a lot like this question: 'return' doesn't jump out of forEach in Kotlin It's just that I don't really get the answers and I don't know if its applicable here. Also a way to implement forEachUntil seems for me to be far more elegant
Alternatives you may want to consider instead of first:
using a simple while without body:
while (checkSet.add(Random.nextInt(n))); // <- that semicolon is required! otherwise you execute what is coming next within the while
using run with a label:
run outForeach#{
generateSequence{ Random.nextInt(n)}.forEach {
if(!checkSet.add(it)) {
return#outForeach
}
}
}
maybe also takeWhile might be helpful. In this specific case however it is surely not (as it would check against the checkSet and leave us with a sequence that isn't consumed... but if the condition would be different, it may make sense to consider something like take, takeWhile, takeLast, etc.):
generateSequence { Random.nextInt(n) }
.takeWhile(checkSet::add) // as said: for this specific condition it doesn't make sense...
.forEach { /* do nothing except consume the sequence */ } // the same values you added to the set would be available in this step of course
I think I found the solution myself:
val checkSet = mutableSetOf<Int>()
generateSequence{ Random.nextInt(n)}.first { !checkSet.add(it) }
sum += checkSet.size
Basically use the function first() and keep returning false until you want to get out of the loop. And just drop the return of the function first()

What is a less verbose way to repeatedly pop() items from a vector?

When using a vector as a stack (storing states which are pushed and popped).
while stack.len() != 0 {
let state = stack.pop().unwrap();
// ... optionally push other states onto the stack.
}
Is there a less verbose way to do this in Rust?
You can use the fact that pop() returns an Option<T> and match on that using a while let loop:
while let Some(state) = stack.pop() {
// ... fine to call stack.push() here
}
The while let desugars to something like the following:
loop {
match stack.pop() {
Some(state) => {
// ... fine to call stack.push() here
}
_ => break
}
}
Just to offer an alternative approach, you can also use the drain method to remove elements and give them to you in an Iterator.
stack.drain(..).map(|element| ...and so on
or
for element in stack.drain(..) {
//do stuff
}
You can also provide a RangeArgument if you only want to remove a certain range of elements. This can be provided in the form of <start-inclusive>..<end-exclusive>. Both the start and end of the range argument are optional and just default to the start of end of the vector, so calling drain(..) just drains the entire vector, while drain(2..) would leave the first 2 elements in place and just drain the rest.

Swift: Random number arrays inside images and variables with a for loop

I am creating a game in which, depending on the number of 'swipes' chosen to do, (let's say 3), 3 different patterns show on the screen, one by one. I am working on developing the first pattern.
So I have this:
if (swipes.no_of_swipes) == 3 {
swipeArray = Array<UInt32>(count: 3, repeatedValue: 0)
for i in 0 ..< 3 {
swipeArray[i] = arc4random_uniform(84)}
}
As far as I am aware, this code creates an array with three UInts which can be accessed by doing swipeArray[0], swipeArray[1], and swipeArray[2]. My first question is how long will this swipeArray stay the same? Until the close the view? Should I have a 'refresh button' when the user loses - and if so, how would I make one?
Then I have a property observer. You will notice the for loop, which I am using to keep code concise. I understand that I could do something like x++ somewhere in here so that it will go through each one.
var playBegin: Bool = false{
didSet {
if playBegin == true {
println("\(playBegin)")
var swipes = Menu()
if (swipes.no_of_swipes) == 3 {
for i in 0 ..< 3 {
patternRoom.image = UIImage(named: "pattern\(swipeArray[x])")
//rest of code
}
}
}
The pattern image comes from a set of 84 images named like pattern7 and pattern56. My second question is, how could I code the for loop to go through each swipeArray[x].
Thank you in advance,
Will
how long will this swipeArray stay the same?
This is a bit too open ended. It’ll stay the same until you assign a new value to it, either from this same bit of code or a different part. Only you can know when that will be, by looking at your code.
Since you express an interest in keeping the code concise, here’s a couple of code tips.
You might think about writing your first snippet’s loop like this:
swipeArray = (0..<swipes.no_of_swipes).map { _ in
arc4random_uniform(84)
}
This combines creating a new array and populating the values. By the way, just in case you don’t realize, there’s no guarantee this array won’t contain the same value twice.
It’s also probably better to make swipeArray of type [Int] rather than [UInt32], and to convert the result of arc4random to an Int straight away:
Int(arc4random_uniform(84))
Otherwise the UInt32s will probably be a pain to work with.
For your second for loop, you can do this:
for i in swipeArray {
patternRoom.image = UIImage(named: "pattern\(i)")
// rest of code
}
When writing Swift, usually (but not always), when you find yourself using array[x] there’s a better more expressive way of doing it.

Resources