Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #37708 > unrolled thread
| Started by | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| First post | 2017-12-01 12:52 -0800 |
| Last post | 2017-12-08 15:00 +0100 |
| Articles | 8 — 3 participants |
Back to article view | Back to comp.lang.java.programmer
Can I put a filter into a lambda? Eric Douglas <e.d.programmer@gmail.com> - 2017-12-01 12:52 -0800
Re: Can I put a filter into a lambda? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-12-01 16:28 -0500
Re: Can I put a filter into a lambda? Eric Douglas <e.d.programmer@gmail.com> - 2017-12-04 05:03 -0800
Re: Can I put a filter into a lambda? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-12-04 08:20 -0500
Re: Can I put a filter into a lambda? Eric Douglas <e.d.programmer@gmail.com> - 2017-12-04 05:32 -0800
Re: Can I put a filter into a lambda? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-12-04 09:29 -0500
Re: Can I put a filter into a lambda? Eric Douglas <e.d.programmer@gmail.com> - 2017-12-04 07:14 -0800
Re: Can I put a filter into a lambda? Sebastian <nowhere@nirvana.org> - 2017-12-08 15:00 +0100
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-12-01 12:52 -0800 |
| Subject | Can I put a filter into a lambda? |
| Message-ID | <321ee28f-bbea-4565-a48e-c0476d9a78d4@googlegroups.com> |
I haven't gotten around to mastering the lambda syntax.
I have a JTable with a custom row sorter building an index of all model rows:
rowToModelIndex.clear();
if (modelRowCount > 0) {
if (getRowFilter() != null) {
for (int r = 0; r < modelRowCount; r++) {
if (include(r)) {
rowToModelIndex.add(r);
}
}
} else {
rowToModelIndex.addAll(Stream.iterate(firstRow, n -> n + 1).limit(modelRowCount).collect(Collectors.toList()));
}
}
If it's a straight up series it's a lambda. Can the filter loop be also? I would guess that would be more efficient.
[toc] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2017-12-01 16:28 -0500 |
| Message-ID | <ovshh6$8q1$1@dont-email.me> |
| In reply to | #37708 |
On 12/1/2017 3:52 PM, Eric Douglas wrote:
> I haven't gotten around to mastering the lambda syntax.
> I have a JTable with a custom row sorter building an index of all model rows:
>
> rowToModelIndex.clear();
> if (modelRowCount > 0) {
> if (getRowFilter() != null) {
> for (int r = 0; r < modelRowCount; r++) {
> if (include(r)) {
> rowToModelIndex.add(r);
> }
> }
> } else {
> rowToModelIndex.addAll(Stream.iterate(firstRow, n -> n + 1).limit(modelRowCount).collect(Collectors.toList()));
> }
> }
>
> If it's a straight up series it's a lambda. Can the filter loop be also? I would guess that would be more efficient.
It's not clear what your filter loop is actually doing:
the RowFilter seems never to be used, and I can't find any
one-argument include() method in any Java SE (8 or 9) class.
(You also haven't shown what rowToModelIndex is, but I'll
guess it's a Collection<Integer>, possibly List<Integer>).
So I'll restate the problem without the table trappings:
1) If getRowFilter() returns null, you want a List of
all the values 0 through modelRowCount-1, in order.
2) If getRowFilter() returns non-null, you want a List
of the same values, excluding those for which the
boolean-valued include(int) method returns false.
If that's not the goal, read no further. But if it is
(or is close enough for jazz), both cases can be written
more simply:
// Case 1:
rowModelIndex = IntStream.range(0, modelRowCount)
.mapToObj(Integer::valueOf)
.collect(Collectors.toList());
// Case 2:
rowModelIndex = IntStream.range(0, modelRowCount)
.filter((value) -> include(value))
.mapToObj(Integer::valueOf)
.collect(Collectors.toList());
Final point: If you can't stop worrying about efficiency,
at the very least stop *guessing* about it!
--
esosman@comcast-dot-net.invalid
Eleven hundred forty-six days to go.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-12-04 05:03 -0800 |
| Message-ID | <a7f8b0f0-79cb-4f83-bf77-2ce7d94a2a19@googlegroups.com> |
| In reply to | #37709 |
On Friday, December 1, 2017 at 4:28:26 PM UTC-5, Eric Sosman wrote: > It's not clear what your filter loop is actually doing: > the RowFilter seems never to be used, and I can't find any > one-argument include() method in any Java SE (8 or 9) class. > (You also haven't shown what rowToModelIndex is, but I'll > guess it's a Collection<Integer>, possibly List<Integer>). > So I'll restate the problem without the table trappings: > > 1) If getRowFilter() returns null, you want a List of > all the values 0 through modelRowCount-1, in order. > > 2) If getRowFilter() returns non-null, you want a List > of the same values, excluding those for which the > boolean-valued include(int) method returns false. > > If that's not the goal, read no further. But if it is > (or is close enough for jazz), both cases can be written > more simply: > > // Case 1: > rowModelIndex = IntStream.range(0, modelRowCount) > .mapToObj(Integer::valueOf) > .collect(Collectors.toList()); > > // Case 2: > rowModelIndex = IntStream.range(0, modelRowCount) > .filter((value) -> include(value)) > .mapToObj(Integer::valueOf) > .collect(Collectors.toList()); > > Final point: If you can't stop worrying about efficiency, > at the very least stop *guessing* about it! > rowToModelIndex is an ArrayList<Integer>. Yes the include method says if the row filter is null then include every row number, if not null then include rows based on the boolean value from the row filter include method. Milliseconds do count in a row filtering method which executes thousands of times.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2017-12-04 08:20 -0500 |
| Message-ID | <p03i39$n76$1@dont-email.me> |
| In reply to | #37712 |
On 12/4/2017 8:03 AM, Eric Douglas wrote:
> On Friday, December 1, 2017 at 4:28:26 PM UTC-5, Eric Sosman wrote:
>> It's not clear what your filter loop is actually doing:
>> the RowFilter seems never to be used, and I can't find any
>> one-argument include() method in any Java SE (8 or 9) class.
>> (You also haven't shown what rowToModelIndex is, but I'll
>> guess it's a Collection<Integer>, possibly List<Integer>).
>> So I'll restate the problem without the table trappings:
>>
>> 1) If getRowFilter() returns null, you want a List of
>> all the values 0 through modelRowCount-1, in order.
>>
>> 2) If getRowFilter() returns non-null, you want a List
>> of the same values, excluding those for which the
>> boolean-valued include(int) method returns false.
>>
>> If that's not the goal, read no further. But if it is
>> (or is close enough for jazz), both cases can be written
>> more simply:
>>
>> // Case 1:
>> rowModelIndex = IntStream.range(0, modelRowCount)
>> .mapToObj(Integer::valueOf)
>> .collect(Collectors.toList());
>>
>> // Case 2:
>> rowModelIndex = IntStream.range(0, modelRowCount)
>> .filter((value) -> include(value))
>> .mapToObj(Integer::valueOf)
>> .collect(Collectors.toList());
>>
>> Final point: If you can't stop worrying about efficiency,
>> at the very least stop *guessing* about it!
>>
> rowToModelIndex is an ArrayList<Integer>.
If it *must* be an ArrayList (and not some other kind of List),
you might want to change the last bit to
.collect(Collectors.toCollection(ArrayList::new));
Although the toList() method appears to use ArrayList anyhow, it
doesn't guarantee to do so -- meaning that it might use some other
List in a future Java, or in circumstances I haven't studies (e.g.,
it might behave differently with a parallel stream).
> Milliseconds do count in a row filtering method which executes thousands of times.
If performance is important, measure. Don't guess.
--
esosman@comcast-dot-net.invalid
Eleven hundred forty-three days to go.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-12-04 05:32 -0800 |
| Message-ID | <9545f24b-39da-4eab-8c65-365a299b3b2a@googlegroups.com> |
| In reply to | #37713 |
On Monday, December 4, 2017 at 8:20:59 AM UTC-5, Eric Sosman wrote: > If it *must* be an ArrayList (and not some other kind of List), > you might want to change the last bit to > > .collect(Collectors.toCollection(ArrayList::new)); > > Although the toList() method appears to use ArrayList anyhow, it > doesn't guarantee to do so -- meaning that it might use some other > List in a future Java, or in circumstances I haven't studies (e.g., > it might behave differently with a parallel stream). > ok, thanks, I'll keep that in mind. I'll have to test if the variable can be assigned and if that would be more efficient. Currently it doesn't matter what kind of list because I made the rowToModelIndex variable final, just calling clear() then addAll(). > > Milliseconds do count in a row filtering method which executes thousands of times. > > If performance is important, measure. Don't guess. > Indeed. I am doing test runs with relatively large data sets.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2017-12-04 09:29 -0500 |
| Message-ID | <p03m3p$ihc$1@dont-email.me> |
| In reply to | #37714 |
On 12/4/2017 8:32 AM, Eric Douglas wrote:
> On Monday, December 4, 2017 at 8:20:59 AM UTC-5, Eric Sosman wrote:
>> If it *must* be an ArrayList (and not some other kind of List),
>> you might want to change the last bit to
>>
>> .collect(Collectors.toCollection(ArrayList::new));
>>
>> Although the toList() method appears to use ArrayList anyhow, it
>> doesn't guarantee to do so -- meaning that it might use some other
>> List in a future Java, or in circumstances I haven't studies (e.g.,
>> it might behave differently with a parallel stream).
>>
> ok, thanks, I'll keep that in mind. I'll have to test if the variable can be assigned and if that would be more efficient. Currently it doesn't matter what kind of list because I made the rowToModelIndex variable final, just calling clear() then addAll().
If you'd rather clear and repopulate the same List (as opposed
to making a new one each time), you could use forEach():
rowModelIndex.clear();
IntStream.range(0, modelRowCount)
.filter((value) -> include(value))
.forEach((value) -> rowModelIndex.add(value);
or
rowModelIndex.clear();
IntStream.range(0, modelRowCount)
.forEach((value) ->
if (include(value)) rowModelIndex.add(value));
I don't know which of these might be faster, or whether either
might be faster than a plain old `for' loop. (Research project.)
FWIW, Brian Goetz (who knows far more about JVM performance
issues than I ever will) indicates that object allocation and
collection is cheaper than commonly thought, so there's little
if any advantage to re-using the same List object:
https://www.ibm.com/developerworks/java/library/j-jtp09275/index.html
... which means even more research may be indicated. (The cited
article is twelve years old, and we may expect that JVM's have
continued to improve meanwhile).
--
esosman@comcast-dot-net.invalid
Eleven hundred forty-three days to go.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-12-04 07:14 -0800 |
| Message-ID | <a706de3b-eafe-47c9-8144-b1ceb04bc495@googlegroups.com> |
| In reply to | #37716 |
On Monday, December 4, 2017 at 9:29:33 AM UTC-5, Eric Sosman wrote: > If you'd rather clear and repopulate the same List (as opposed > to making a new one each time), you could use forEach(): > > rowModelIndex.clear(); > IntStream.range(0, modelRowCount) > .filter((value) -> include(value)) > .forEach((value) -> rowModelIndex.add(value); > > or > > rowModelIndex.clear(); > IntStream.range(0, modelRowCount) > .forEach((value) -> > if (include(value)) rowModelIndex.add(value)); > > I don't know which of these might be faster, or whether either > might be faster than a plain old `for' loop. (Research project.) > Thanks! I'll check it out. > FWIW, Brian Goetz (who knows far more about JVM performance > issues than I ever will) indicates that object allocation and > collection is cheaper than commonly thought, so there's little > if any advantage to re-using the same List object: > > https://www.ibm.com/developerworks/java/library/j-jtp09275/index.html > > ... which means even more research may be indicated. (The cited > article is twelve years old, and we may expect that JVM's have > continued to improve meanwhile). > I'd have to take another look at their code for clear() and addAll(), I would guess generating a new variable might be cheaper, but the functional difference is more important. I'd have to check if I have something else grabbing a reference to this variable just expecting it to get updated values rather than needing to get the reference to a new variable. I believe I did that, though offhand can't recall why.
[toc] | [prev] | [next] | [standalone]
| From | Sebastian <nowhere@nirvana.org> |
|---|---|
| Date | 2017-12-08 15:00 +0100 |
| Message-ID | <p0e5us$eiv$1@news.albasani.net> |
| In reply to | #37716 |
Am 04.12.2017 um 15:29 schrieb Eric Sosman: > > I don't know which of these might be faster, or whether either > might be faster than a plain old `for' loop. (Research project.) > > FWIW, Brian Goetz (who knows far more about JVM performance > issues than I ever will) indicates that object allocation and > collection is cheaper than commonly thought, so there's little > if any advantage to re-using the same List object: > > https://www.ibm.com/developerworks/java/library/j-jtp09275/index.html > > ... which means even more research may be indicated. (The cited > article is twelve years old, and we may expect that JVM's have > continued to improve meanwhile). > Angelika Langer did some research into the performance of streams vs. for loops when JDK 8 came out. It's referenced from this article, which puts performance, readability and maintainability into perspective: https://blog.jooq.org/2015/12/08/3-reasons-why-you-shouldnt-replace-your-for-loops-by-stream-foreach/ -- Sebastian
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web