Skip to content

Conversation

@zbynek
Copy link
Collaborator

@zbynek zbynek commented Nov 16, 2025

Fixes #9495 by changing the error message.

@zbynek zbynek added Category-JRE ready This PR has been reviewed by a maintainer and is ready for a CI run. labels Nov 16, 2025
@niloc132 niloc132 added this to the 2.13 milestone Nov 18, 2025
Copy link
Member

@niloc132 niloc132 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good, thanks for taking the extra steps here. I think we can get better, but I don't think its worth doing now - and the fixes touch a lot more of the class (and besides, they are going back to the first impl that we did for this class).

I did some compiled size testing. My methodology:

  • set test.args in user/build.xml to -ea -sourceLevel auto -setProperty compiler.useSourceMaps=true so that we avoid using emulated stack traces, and get more realistic JS output
  • run all CollectorsTest impls by making a single CollectorsSuite
    package com.google.gwt.emultest.java17;
    
    import org.junit.runner.RunWith;
    import org.junit.runners.Suite;
    
    @RunWith(Suite.class)
    @Suite.SuiteClasses({
      com.google.gwt.emultest.java8.util.stream.CollectorsTest.class,
      com.google.gwt.emultest.java9.util.stream.CollectorsTest.class,
      com.google.gwt.emultest.java10.util.stream.CollectorsTest.class,
      com.google.gwt.emultest.java17.util.stream.CollectorsTest.class,
    })
    public class CollectorsSuite {
    }
  • Run just that suite in prod mode in the user/ dir: ant test.web.htmlunit '-Dgwt.junit.testcase.includes=**/CollectorsSuite.class'
  • Check the compiled size, with something like ls -al ../build/out/user/test/web-htmlunit/www/com.google.gwt.emultest.EmulSuite.JUnit/*.cache.js

HEAD, plus your test change (with two failing tests), currently d67edbb: 153033
latest commit in this PR, currently 07617ec, merged up to latest main: 153339

306 bytes over 150kb isn't bad, and probably not entirely driven by lambdas (additional null checks, etc). Percentage wise, its not great - but this will not scale, it'll be the max size increase that this change can cause over a full app, since its not like an app would load multiple copies of Collectors. Generally this is all keeping with the work done this release to improve emulation, so I'd vote worth it, and we can focus more on improved compiled size next release.

@niloc132
Copy link
Member

niloc132 commented Dec 4, 2025

Quick draft - harms readability IMHO, but improves size, down to 151919151762 using the tests above. Unsure about performance, we should add some testing here as well, but I think it is a mild improvement in at least one case (moving an if outside of a lambda so it is only checked once).
Two-ish techniques taking place here:

  • First, any duplication of method references gets extracted to a helper method - those will all be rewritten to just constructor calls and inlined, so there's no extra cost to them. Might become largely unnecessary if we find a nice way to resolve Explore method reference sharing, function deduplication #10160.
  • Second, when a Collector.of(...) call would take multiple lambdas/method references, make a single class that implements all of them at once. I only did this for a single case of four method references, and it only saved about 60 bytes (while creating a lot more input Java). Maybe thats not much, but if we're confident in the tests and we apply it everywhere, that's probably 2-300 bytes saved overall any application that uses most of the collectors... Still probably only barely worth it.

@niloc132 niloc132 merged commit a0bbaf0 into gwtproject:main Dec 5, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Category-JRE ready This PR has been reviewed by a maintainer and is ready for a CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve Collectors.toMap(Function,Function) error message for duplicate keys

2 participants