8000 Introduce ArrayList type that will map to native js Array · Issue #30772 · dart-lang/sdk · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Introduce ArrayList type that will map to native js Array #30772

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ranquild opened this issue Sep 18, 2017 · 8 comments
Closed

Introduce ArrayList type that will map to native js Array #30772

ranquild opened this issue Sep 18, 2017 · 8 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-stale Closed as the issue or PR is assumed stale type-enhancement A request for a change that isn't a bug

Comments

@ranquild
Copy link

Currently there is no way to specify type that is "default" List implementation. Dart2js uses type inference for optimizations, however in real world it is unable infer type in most cases. What I suggest is to add unextandable ArrayList type in dart:collection that dart2js will know about.

@lrhn lrhn added area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). type-enhancement A request for a change that isn't a bug area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. labels Sep 18, 2017
@ranquild
Copy link
Author
ranquild commented Sep 22, 2017

@rakudrama @jmesserly Any thoughts on this? While this issue seems insignificant, List iteration/manipulation performance is major issue in our code. In most of times code that work with List ends up with calling interceptor methods for all operations.

@rakudrama
Copy link
Member

I think access to the built-in List types would be useful. I see the what you describe in many places.

@floitschG This is a question for the Libraries team. Whatever we do, we need to support it widely to permit sharing of business logic between Dart web apps and Flutter mobile apps.

One problem is that on the VM there are several types (growable, fixed-length and immutable (const-like) Lists are three different types), but in JavaScript and dart2js there is one (JavaScript Array is used for all variants).

Another problem is that the benefits might be transient. Some library might implement a fake version of that type, bringing us back to there being many types and a need for getInceptor, e.g.

class MockArrayList<T> implements ArrayList<T> { ... }

There are coding styles that can help dart2js's type analysis.
One is to use final fields and initialize them to the new list

class ... {
  final _list = []; // Trivial inference.

It feels counterintuitive, but you might get better inference results from wrapping arrays to exploit the above trivial inference.

One thing we are considering is specializing the library code for (JS)Array. Today if you write a.map(transform).toList(), map is implemented by MappedListIterable, which uses ListIterator. In a nontrivial program, ListIterator is used for many kinds of list, so ListIterator.moveNext ends up using getInterceptor for each call. If JSArray had its own map() iterable, say ArrayMapIterable, then ArrayMapIterable.toList could directly index the Array. You would get this benefit even if one getInterceptor call was needed at a.map to get 'into' the specialized code.

@jmesserly
Copy link
jmesserly commented Sep 22, 2017

I'm strongly in favor of this, for what it's worth.

EDIT: though we would want this type to be non-implementable/non-extensible, similar to some of the existing dart:core types.

@matanlurey
Copy link
Contributor

+1.

The other option in my mind is creating a library of JS-level primitives for optimization:

/// A `List`-like object guaranteed to be 1:1 mapped to a JavaScript `Array`.
///
/// May be used internally in frameworks that are browser-only in order to avoid
/// interceptors and other de-optimized code in Dart to JavaScript compilers that
/// needs to support polymorphic Dart `List` types.
abstract class JSArray<T> {
  // Assume compilers can know new JSArray([1, 2, 3]) really means [1, 2, 3]
  external JSArray(List<T> from);

  T operator[](int index);
  void operator[]=(int index, T value);

  List<T> toDartList();
}

@matanlurey
Copy link
Contributor

Here are other silly ideas: #30870

@ranquild
Copy link
Author

Another option that would work for us is new primitive Array type, that will not implement List and will work like in C# or Java.

@rakudrama
Copy link
Member

I'm interested in someone doing an experiment to see how much we can get from wrappers which help dart2js with inference. I don't have the capacity to follow up on this until next year.

This library contains Array (fixed length) and ArrayList (growable) classes that should always be nicely inferred by dart2js provided you change various types in your program from List to one of these types. This should be pretty close to what you would get from the proposed special type known to the compiler.

https://github.com/rakudrama/array_list

@lrhn
Copy link
Member
lrhn commented Jun 22, 2018

tl;dr: I don't see this happening in the core platform libraries.

Most of the optimizations here are really JavaScript only, and would detract from the non-JavaScript APIs. A JSArray class would fit in well in JS-interop, but wouldn't make sense on the VM.

We keep the implementation classes for List (and other general interfaces) private because we want to reserve the ability to change them in the future. The VM can introduce a new DenseHashMap implementation at any point.
We could introduce an interface like PlatformList which is implemented only by the platform list implementations (well, some of them, probably not the one returned by List.codeUnits).
It wouldn't differ from List at all, so it's really just a marker interface. We try to avoid those, since they separate classes into two groups without any functional reason behind it (same interface). You could call it a "class hierarchy fragmentation" issue.
The second someone makes a function which only accepts platform lists, we have now introduced a new mental overhead for everybody using lists. Should I accept only a platform list or a general list? If I accept any list, I can't call that fancy function. If I only accept platform lists, everybody else now needs to consider the same when calling me.
The feature just doesn't carry its own weight, as measured in complexity for users.

Long ago, in 2012, we briefly had a Sequence interface which was basically class with length and integer indexing (and both String and List were sequences). Even that was not considered worth its own weight, and was removed again after ~1 month.

@lrhn lrhn closed this as not planned Won't fix, can't repro, duplicate, stale Apr 9, 2025
@lrhn lrhn added the closed-stale Closed as the issue or PR is assumed stale label Apr 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-stale Closed as the issue or PR is assumed stale type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

5 participants
0