Hi Folks!
fastutil is an amazing lib. Thank you for creating it!!!!!! I
discovered it a few weeks ago and it boosted my
productivity!!!
Suggestion:
Although fastutil has a good documentation, getting started was
sometimes a bit bumby. It would have helped me to have a quick
read-over FAQ for new users which shows a few simple use cases that many users will want to try out first. I couldn't find one, and I still have
a few open questions (see below).
During my adaption of fastutil, I've compiled a list of questions for which I couldn't find
the answer straightforward (or not at all). I've also added some suggestions for
changes/additions. This list can serve as a basis for such an FAQ.
The suggestions might be good or they might depend on personal
taste, so if you don't like them I won't take up the cudgels for
them; e.g. I might just have a different taste for naming
conventions. Other suggestions can also be interpreted as a
question, like "This is the best idea I had to solve some problem.
Is there a better way to do it?" - check back with me if you have
the feeling that some discussion might foster understanding what
I'm after.
Here is the list:
1. How to sort an IntArrayList?
Found it:
IntArrayList list = ...;
list.sort(IntComparators.NATURAL_COMPARATOR);
2.1. fastutil is cool. However, I wonder why I can't find
IntArrayList.swap(i,j). I need that often. Is there a reason, or a
better way to do a swap?
2.2. I sometimes like to use Lists of counters. It looks clumsy when I write intList.set(i, list.getInt(i) + 1). the maps have this excellent method addTo(int index, int incr). Can we have this for lists as well? It might not increase the performance, but it's definitely more readable like this: intList.addTo(i, 1).
2.3. Sometimes I need to set or addTo on ranges, or on all elements. I'd love to have an intList.set(int fromIndex, int toIndex, int value), and an addTo() of the same flavour. For even more convenience and readability, setAll() and addToAll() would be the ultimate gimmick.
2.4. Is there a way to transform each element of a list in the same way? e.g. with an Int2IntFunction, like intList.forEach((int k) -> 2 * k + 1); Would be pretty darn cool to have this!
3. What's the fastest way to read-iterate over an IntArrayList? -
with iterator or with for (int i = 0; ...) { ... list.getInt(i)
... }? Is there anything faster that I'm not aware of?
Or does it not matter?
cf the same question on SO:
https://stackoverflow.com/questions/61855626/best-practice-for-iterating-over-fastutil-primitive-arraylists
4. What's slow and should be avoided in favour of good
performance?
I found this in Eclipse to help me:
Window -> Preferences -> Java -> Compiler ->
Errors/Warnings
-> Potential Programming Problems -> Boxing and unboxing
conversions
-> set to Warning
However, I'm sure it doesn't flag all cases of autoboxing,
thus it has limited
usefulness.
Is there any other advice what to avoid and what to do?
5.1. How to presize a list? / 5.2. How to add an element
multiple times?
Found presizing:
IntArrayList list = new IntArrayList(n);
list.size(n);
5.2. remains: How to add an element multiple times to an
existing list?
Concerning 4.1.:
Having 2 lines of code just for a presized list is clumsy. Is
there a 1-line-way to make it size n, like new IntArrayList(n,
true) or new IntArrayList(n, n)?
6. I saw IntArrayList.topInt(). Is there .bottomInt()? If not, it
should be added. And maybe adjust the naming conventions, e.g.
that of c++ std::vector: back() / front(), and maybe also data()
or storage() instead of elements(). It took me some time to find
elements().
7. How to best wrap (not copy) an int[] so it can be used as a
collection or as an IntIterable?
Found it:
IntListIterator iter = IntIterators.wrap(int[] array)
8. How to reverse the elements in a list? (NOT: how to sort with
reverse order of a Comparator; that's something different)
9. I can use IntArrays.quickSort(int[] x, int[] y) to sort two
int[] arrays as if their elements at equal indices were one
element. That's great and I missed this a lot in std Java.
How to do the same for an int[] and a long[], or for an
IntArrayList and a LongArrayList? (or for two lists of the same
type, e.g. two IntArrayLists; couldn't find that, just workaround
with same style as in question 10.)
10. How to do a binary search on a LongArrayList?
I found the workaround
LongArrays.binarySearch(longArrayList.elements(), 0,
longArrayList.size(), key); // but that looks clumsy, lacks
clarity
11. In addition to Int2IntMap.addTo(int k, int incr), I'd like to
have Int2IntMap.addToExact(int k, int incr), which uses
Math.addExact() for the addition.
12. It would make sense to allow usage of type specific lambdas on
maps like we have it for lists. This is faster than
int2intMap.int2IntEntrySet().fastForEach((Int2ObjectMap.Entry<MyObj>
entry) -> {}), because it gets rid of the entry instance
alltogether, and it is also much faster than the
.forEach(BiConsumer<Integer, Integer>), because the latter
style heavily involves autoboxing. Moreover the suggested way
results in cleaner code, because it doesn't require the
getIntKey(), getIntValue() methods:
Int2IntOpenHashMap int2IntMap = null;
// current way
int2IntMap.int2IntEntrySet().fastForEach((Int2IntMap.Entry
entry) -> {
int key = entry.getIntKey();
int value = entry.getIntValue();
System.out.println(key + " => " + value);
});
// proposed way
int2IntMap.forEach((IntIntBiConsumer) (int key, int value)
-> {
System.out.println(key + " => " + value);
});
// for this to work, we need the following interface
@FunctionalInterface
public interface IntIntBiConsumer extends
BiConsumer<Integer, Integer> {
public void accept(int t, int u);
default public void accept(Integer t, Integer u) {
accept(t.intValue(), u.intValue());
}
}
13. The documentation of fastutil is excellent. I still have a (very minor) critique:
The API doc is sometimes inherited to sublclasses. That's ok
together with a note about this fact, like for
IntArrayList.add(int index, int k): "Description copied from
class: AbstractIntList...". However, this note is not shown in
Eclipse, which had tricked me to believe that I can't use this
method at all, because it says that the implementation was
missing:
Very Best,
Daniel
Hi Folks!
Suggestion:
Although fastutil has a good documentation, getting started was sometimes a bit bumby. It would have helped me to have a quick read-over FAQ for new users which shows a few simple use cases that many users will want to try out first. I couldn't find one, and I still have a few open questions (see below).
2.1. fastutil is cool. However, I wonder why I can't find IntArrayList.swap(i,j). I need that often. Is there a reason, or a better way to do a swap?
2.2. I sometimes like to use Lists of counters. It looks clumsy when I write intList.set(i, list.getInt(i) + 1). the maps have this excellent method addTo(int index, int incr). Can we have this for lists as well? It might not increase the performance, but it's definitely more readable like this: intList.addTo(i, 1).
2.4. Is there a way to transform each element of a list in the same way? e.g. with an Int2IntFunction, like intList.forEach((int k) -> 2 * k + 1); Would be pretty darn cool to have this!
3. What's the fastest way to read-iterate over an IntArrayList? - with iterator or with for (int i = 0; ...) { ... list.getInt(i) ... }? Is there anything faster that I'm not aware of?
4. What's slow and should be avoided in favour of good performance?
I found this in Eclipse to help me:
Window -> Preferences -> Java -> Compiler -> Errors/Warnings
-> Potential Programming Problems -> Boxing and unboxing conversions
-> set to Warning
However, I'm sure it doesn't flag all cases of autoboxing, thus it has limited
usefulness.
Is there any other advice what to avoid and what to do?
5.2. remains: How to add an element multiple times to an existing list?
Concerning 4.1.:
Having 2 lines of code just for a presized list is clumsy. Is there a 1-line-way to make it size n, like new IntArrayList(n, true) or new IntArrayList(n, n)?
6. I saw IntArrayList.topInt(). Is there .bottomInt()? If not, it should be added. And maybe adjust the naming conventions, e.g. that of c++ std::vector: back() / front(), and maybe also data() or storage() instead of elements(). It took me some time to find elements().
7. How to best wrap (not copy) an int[] so it can be used as a collection or as an IntIterable?
Found it:
IntListIterator iter = IntIterators.wrap(int[] array)
8. How to reverse the elements in a list? (NOT: how to sort with reverse order of a Comparator; that's something different)
9. I can use IntArrays.quickSort(int[] x, int[] y) to sort two int[] arrays as if their elements at equal indices were one element. That's great and I missed this a lot in std Java.
How to do the same for an int[] and a long[], or for an IntArrayList and a LongArrayList? (or for two lists of the same type, e.g. two IntArrayLists; couldn't find that, just workaround with same style as in question 10.)
11. In addition to Int2IntMap.addTo(int k, int incr), I'd like to have Int2IntMap.addToExact(int k, int incr), which uses Math.addExact() for the addition.
12. It would make sense to allow usage of type specific lambdas on maps like we have it for lists.
13. The documentation of fastutil is excellent. I still have a (very minor) critique:
The API doc is sometimes inherited to sublclasses. That's ok together with a note about this fact, like for IntArrayList.add(int index, int k): "Description copied from class: AbstractIntList...". However, this note is not shown in Eclipse, which had tricked me to believe that I can't use this method at all, because it says that the implementation was missing:
Very Best,
Daniel