, das im Grunde genommen ein Array explizit konstruiert und dann jedes Element mit ordargumenten kombiniert
Dies funktioniert, aber der resultierende MethodeHandle erzeugt StackoverFlowerror Bei der Erstellung großer Arrays (sayer 100K -Elemente). Aus den Dokumenten auf Ordnungen ist dies sinnvoll, da jeder Aufruf eine Struktur des Schwanzaufrufs einstellt.
static makeArray(InternalContext ctx) {
var a = new Object[
Ich habe festgestellt, dass ich dies mit Rekursion lösen kann < /p>
static MethodHandle buildLargeArrayRecursive(List elementFactories) {
// (Object[], InternalContext) -> void
var handle = doBuildLargeArrayRecursive(0, elementFactories);
// (Object[], InternalContext) -> Object[]
handle =
MethodHandles.foldArguments(
MethodHandles.dropArguments(
MethodHandles.identity(Object[].class), 1, InternalContext.class),
handle);
;
return MethodHandles.foldArguments(
handle,
MethodHandles.insertArguments(
MethodHandles.arrayConstructor(Object[].class), 0, elementFactories.size()));
}
static final MethodHandle ARRAY_SETTER = MethodHandles.arrayElementSetter(Object[].class);
static MethodHandle doBuildLargeArrayRecursive(int offset, List elementFactories) {
int size = elementFactories.size();
if (size == 0) {
return MethodHandles.empty(methodType(void.class, Object[].class, InternalContext.class));
}
if (size == 1) {
return MethodHandles.filterArguments(
MethodHandles.insertArguments(ARRAY_SETTER, 1, offset), 1, elementFactories.get(0));
}
int half = size / 2;
var left = elementFactories.subList(0, half);
var right = elementFactories.subList(half, size);
return MethodHandles.foldArguments(
doBuildLargeArrayRecursive(offset + half, right), doBuildLargeArrayRecursive(offset, left));
}
< /code>
, was auf mindestens 100.000 Elemente zu skalieren scheint. Aber dies ist eindeutig, dass dies O (logn) Stapelraum verbraucht. Das ist wahrscheinlich in Ordnung, aber dies sind auch viele Methodenaufrufe ... < /p>
Ein paar Dinge sind aufgetreten, während ich darauf starrte: < /p>
Sollte ich Helfer-Bulk-Set-Methoden erstellen, um mehr Basisfälle zu behandeln? z.B. static void set4 (Objekt [], int offset, Objekt O1 ... Objekt O3) {...}
könnte dazu beitragen, die Rekursion zu verringern? Oder sollte ich mich nur auf die VM verlassen, um dies durch das Inline -Inline zu tun? /> Wäre es besser, kleine Arrays zu konstruieren und sie mit System zusammenzusetzen.>
Ich muss einen MethodHandle mit Signature (Internalcontext)-> Objekt [] Aus einer Liste mit der Signatur (Internalcontext)-> Objekt .[code] static MethodHandle makeArrayUsingCollector(List elements) { // (Object[]) -> Object[] var handle = MethodHandles.identity(Object[].class); // (Object,Object...Object) -> Object[] handle = handle.asCollector(Object[].class, elements.size()); // (InternalContext,InternalContext..InternalContext) -> Object[] handle = MethodHandles.filterArguments(handle, 0, elements.toArray(new MethodHandle[0])); // (InternalContext) -> Object[] handle = MethodHandles.permuteArguments( handle, methodType(Object[].class, InternalContext.class), new int[elements.size()]); return handle; } [/code] Wenn die Liste jedoch größer ist, fehl[code] private static final int MAX_ARITY = 255;
static MethodHandle buildLargeArrayNaive(List elementFactories) { if (elementFactories.size() < MAX_ARITY) { return makeArrayUsingCollector(elementFactories); } var setter = MethodHandles.arrayElementSetter(Object[].class); // (Object[], InternalContext) -> void MethodHandle handle = null; for (int i = 0; i < elementFactories.size(); i++) { // (Object[], InternalContext) -> void var setElement = MethodHandles.filterArguments( MethodHandles.insertArguments(setter, 1, i), 1, elementFactories.get(i)); if (handle == null) { handle = setElement; } else { handle = MethodHandles.foldArguments(setElement, handle); } }
// (Object[], InternalContext) -> Object[] handle = MethodHandles.foldArguments( MethodHandles.dropArguments( MethodHandles.identity(Object[].class), 1, InternalContext.class), handle); return MethodHandles.foldArguments( handle, MethodHandles.insertArguments( MethodHandles.arrayConstructor(Object[].class), 0, elementFactories.size())); } [/code] , das im Grunde genommen ein Array explizit konstruiert und dann jedes Element mit ordargumenten kombiniert Dies funktioniert, aber der resultierende MethodeHandle erzeugt StackoverFlowerror Bei der Erstellung großer Arrays (sayer 100K -Elemente). Aus den Dokumenten auf Ordnungen ist dies sinnvoll, da jeder Aufruf eine Struktur des Schwanzaufrufs einstellt.[code]static makeArray(InternalContext ctx) { var a = new Object[ Ich habe festgestellt, dass ich dies mit Rekursion lösen kann < /p> static MethodHandle buildLargeArrayRecursive(List elementFactories) { // (Object[], InternalContext) -> void var handle = doBuildLargeArrayRecursive(0, elementFactories); // (Object[], InternalContext) -> Object[] handle = MethodHandles.foldArguments( MethodHandles.dropArguments( MethodHandles.identity(Object[].class), 1, InternalContext.class), handle); ; return MethodHandles.foldArguments( handle, MethodHandles.insertArguments( MethodHandles.arrayConstructor(Object[].class), 0, elementFactories.size())); }
static final MethodHandle ARRAY_SETTER = MethodHandles.arrayElementSetter(Object[].class);
static MethodHandle doBuildLargeArrayRecursive(int offset, List elementFactories) { int size = elementFactories.size(); if (size == 0) { return MethodHandles.empty(methodType(void.class, Object[].class, InternalContext.class)); } if (size == 1) { return MethodHandles.filterArguments( MethodHandles.insertArguments(ARRAY_SETTER, 1, offset), 1, elementFactories.get(0)); } int half = size / 2; var left = elementFactories.subList(0, half); var right = elementFactories.subList(half, size); return MethodHandles.foldArguments( doBuildLargeArrayRecursive(offset + half, right), doBuildLargeArrayRecursive(offset, left)); } < /code> , was auf mindestens 100.000 Elemente zu skalieren scheint. Aber dies ist eindeutig, dass dies O (logn) Stapelraum verbraucht. Das ist wahrscheinlich in Ordnung, aber dies sind auch viele Methodenaufrufe ... < /p> Ein paar Dinge sind aufgetreten, während ich darauf starrte: < /p>
Sollte ich Helfer-Bulk-Set-Methoden erstellen, um mehr Basisfälle zu behandeln? z.B. static void set4 (Objekt [], int offset, Objekt O1 ... Objekt O3) {...} [/code] könnte dazu beitragen, die Rekursion zu verringern? Oder sollte ich mich nur auf die VM verlassen, um dies durch das Inline -Inline zu tun? /> Wäre es besser, kleine Arrays zu konstruieren und sie mit System zusammenzusetzen.>
Ich muss einen MethodHandle mit Signature (Internalcontext)-> Objekt [] Aus einer Liste mit der Signatur (Internalcontext)-> Objekt . static MethodHandle makeArrayUsingCollector(List elements) {
//...
Ich habe in Telegram viel über die Rich-Link-Vorschau gesehen oder nachgefragt, aber hier geht es speziell darum, „wie man ein GROSES/GROSSES Bild in der Vorschau erhält.
Ich muss ersatzlose Zufallsstichproben aus einem 1D-NumPy-Array ziehen. Allerdings ist die Leistung von entscheidender Bedeutung, da dieser Vorgang viele Male wiederholt wird.
Hier ist der Code, den...