Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

czyszczenie tablicy.

441 views
Skip to first unread message

Jarek

unread,
Apr 25, 2005, 5:41:05 AM4/25/05
to
Witam

Jak wyczyscic tablice?Czy wystarczy np.
a = null;
i bedzie oki?Czy jest jakas metoda?Przegrzebalem klase java.util Class
Arrays ale nie znalazlem jakies metody.

Pozdrawiam
Jarek Z.


wrobel.cwirek

unread,
Apr 25, 2005, 6:22:27 AM4/25/05
to
Użytkownik "Jarek" <jar...@o2.pl> napisał w wiadomości
news:d4ieaj$m3l$1...@nemesis.news.tpi.pl...

>
> Jak wyczyscic tablice?Czy wystarczy np.
> a = null;
> i bedzie oki?Czy jest jakas metoda?Przegrzebalem klase java.util Class
> Arrays ale nie znalazlem jakies metody.
>
Powinno być ok, a jak chcesz na sile to jeszcze mozesz zrobic
Arrays.fill(tablica, null);


Piotr Kobzda

unread,
Apr 25, 2005, 9:21:23 AM4/25/05
to

Będzie "oki". Oba zresztą sposoby są poprawne. Różnice mogą kryć się w
wydajności ogólnej (algorytmy GC kontra fill()) -- trudno jednak
jednoznacznie stwierdzić co i kiedy będzie szybsze?...
Array.fill() to prosta pętla przypisująca każdemu elementowi podaną
wartość, jeśli wykonuje się sporo takich czyszczeń, a tablica nie jest
za duża, to wypełnianie może okazać się szybsze od algorytmów GC
sprzątających przy każdym przejściu także instancję tablicy ...
Przeważnie jednak algorytmy GC zwycięsko z pojedynku wychodzą.

Nieco inaczej sytuacja się ma, gdy trzeba, by początkową wartością
tablicy było coś innego niż wartość domyślna, wtedy pętlę taką w celu
przygotowania "nowej tablicy" trzeba będzie i tak wykonać.
Jeśli nadto tablica jest duża, to wypełnianiem tablicy najlepiej samemu
się zająć :) ... a największym problemem jest wtedy stwierdzenie, czy
tablica jest już duża?...

Zainteresowanym proponuję porównanie wydajności Array.fill() z czymś takim:

public static void fill(Object[] a, int fromIndex, int toIndex, Object
val) {
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex+")");
if (fromIndex < 0)
throw new ArrayIndexOutOfBoundsException(fromIndex);
if (toIndex > a.length)
throw new ArrayIndexOutOfBoundsException(toIndex);

final int size = toIndex - fromIndex;
final int threshold = size < 24 ? size :
(size < 48 ? ((size >> 1) + (size & 1)) : 16);

int s = 0;
for(; s < threshold; ++s)
a[fromIndex + s] = val;
for(; s <= size - s; s <<= 1)
System.arraycopy(a, fromIndex, a, fromIndex + s, s);
if (s < size)
System.arraycopy(a, fromIndex, a, fromIndex + s, size - s);
}


P.S.
Eksperymentalnie dobrany został 'threshold' (Java 1.5.0 i W2K). Gdyby
komuś ciekawsza formuła na myśl przyszła, to za chęć podzielenia się nią
TIA!


piotr

Piotr Lipson

unread,
Apr 25, 2005, 12:07:33 PM4/25/05
to

> Zainteresowanym proponuję porównanie wydajności Array.fill() z czymś takim:
> ...

U mnie jest ta twoja metoda jakies 4 razy szybsza... ale opcja "-server"
powoduje ze twoja jest szybsza o 12%.

Niech mi ktos wyjasni z jakiego powodu SUN nie weźmie maszyny server do
JRE i jako default?? w JRE jest tylko hotspot, który jakos najwyrazniej
niebardzo kwapi sie zeby kompilowac to co trzeba :|... no ale za to
uruchamia jakies 2 sekundy szybciej... Kali nie kumać.

Piotr Kobzda

unread,
Apr 26, 2005, 7:57:17 AM4/26/05
to

Piotr Lipson wrote:
> U mnie jest ta twoja metoda jakies 4 razy szybsza... ale opcja "-server"
> powoduje ze twoja jest szybsza o 12%.

Hmmm... u mnie opcja -server nie zmienia aż tak drastycznie osiągów
Arrays.fill().

Może próbowałeś z wcześniejszą Javą ? ... w 'piątce' poprawiono
wydajność, m.in. właśnie System.arraycopy() (choć tu akurat nie więcej
niż 10%) ...

Mógłbyś może podać wyniki testów podobnych moim (źródło na końcu) ?
Jeśli komuś wskaźnik 't0/t1%' znacznie odbiega od podanych tutaj, to
gdy poinformować tu o wynikach swych zechce, także mile widzianym będzie.


Środowisko testowe:
Windows 2000, 1 x CPU 2,4GHz, 1GB RAM

C:\Java\testy>java -version
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)


C:\Java\testy>java -Xprof ArrayFillTest 10000 5000 10
t0: 1031
t1: 203
t0: 1032
t1: 203
t0: 1015
t1: 204
t0: 1031
t1: 203
t0: 1031
t1: 188
t0: 1016
t1: 203
t0: 1031
t1: 203
t0: 1032
t1: 187
t0: 1047
t1: 187
t0: 1032
t1: 203
args: size=10000, loops=5000, trys=10
t0 avg: 1029 (min/max: 1015/1047)
t1 avg: 198 (min/max: 187/204)
t0/t1%: 519,70%

Flat profile of 12.34 secs (842 total ticks): main

Interpreted + native Method
0.1% 1 + 0 java.util.Currency.getInstance
0.1% 1 + 0 ArrayFillTest.main
0.1% 1 + 0 java.util.jar.JarFile.hasClassPathAttribute
0.1% 0 + 1 java.io.FileOutputStream.writeBytes
0.5% 3 + 1 Total interpreted

Compiled + native Method
82.3% 693 + 0 java.util.Arrays.fill
14.0% 118 + 0 ArrayFillTest.fill
2.0% 17 + 0 ArrayFillTest.main
1.2% 10 + 0 java.util.Arrays.fill
99.5% 838 + 0 Total compiled


Flat profile of 0.01 secs (1 total ticks): DestroyJavaVM

Thread-local ticks:
100.0% 1 Blocked (of total)


Global summary of 12.35 seconds:
100.0% 844 Received ticks


C:\Java\testy>java -server -Xprof ArrayFillTest 10000 5000 10
t0: 1219
t1: 234
t0: 1203
t1: 172
t0: 781
t1: 203
t0: 594
t1: 203
t0: 594
t1: 203
t0: 610
t1: 203
t0: 593
t1: 204
t0: 593
t1: 203
t0: 594
t1: 188
t0: 593
t1: 203
args: size=10000, loops=5000, trys=10
t0 avg: 737 (min/max: 593/1219)
t1 avg: 201 (min/max: 172/234)
t0/t1%: 366,67%

Flat profile of 9.45 secs (641 total ticks): main

Interpreted + native Method
0.3% 2 + 0 ArrayFillTest.fill
0.2% 1 + 0 java.util.Arrays.fill
0.2% 1 + 0
java.security.BasicPermission.newPermissionCollection
0.2% 0 + 1 java.io.FileOutputStream.writeBytes
0.2% 0 + 1 java.util.zip.ZipFile.open
0.2% 0 + 1 java.lang.System.arraycopy
0.2% 1 + 0 java.util.ResourceBundle.getLoader
0.2% 1 + 0 ArrayFillTest.fill
0.2% 0 + 1 java.lang.Class.getComponentType
0.2% 1 + 0 ArrayFillTest.main
1.7% 7 + 4 Total interpreted

Compiled + native Method
52.4% 335 + 1 ArrayFillTest.main
28.7% 184 + 0 adapters
17.0% 109 + 0 ArrayFillTest.fill
0.2% 1 + 0 java.util.Arrays.fill
98.3% 629 + 1 Total compiled


Flat profile of 0.00 secs (1 total ticks): DestroyJavaVM

Thread-local ticks:
100.0% 1 Blocked (of total)


Global summary of 9.46 seconds:
100.0% 643 Received ticks
0.5% 3 Compilation


C:\Java\testy>java -Xint -Xprof ArrayFillTest 10000 5000 10
t0: 3437
t1: 235
t0: 3437
t1: 219
t0: 3437
t1: 219
t0: 3453
t1: 219
t0: 3437
t1: 235
t0: 3437
t1: 219
t0: 3453
t1: 219
t0: 3437
t1: 235
t0: 3437
t1: 219
t0: 3453
t1: 219
args: size=10000, loops=5000, trys=10
t0 avg: 3441 (min/max: 3437/3453)
t1 avg: 223 (min/max: 219/235)
t0/t1%: 1543,05%

Flat profile of 36.71 secs (2525 total ticks): main

Interpreted + native Method
92.9% 2346 + 0 java.util.Arrays.fill
5.6% 0 + 142 java.lang.System.arraycopy
1.1% 27 + 0 ArrayFillTest.fill
0.1% 2 + 0 java.util.Arrays.rangeCheck
0.1% 0 + 2 java.io.FileOutputStream.writeBytes
0.1% 2 + 0 ArrayFillTest.fill
0.0% 1 + 0 java.util.HashMap.<init>
0.0% 1 + 0 java.util.Formatter.setZero
0.0% 1 + 0 java.util.jar.JarFile.hasClassPathAttribute
0.0% 1 + 0 ArrayFillTest.main
100.0% 2381 + 144 Total interpreted


Flat profile of 0.00 secs (1 total ticks): DestroyJavaVM

Thread-local ticks:
100.0% 1 Blocked (of total)


Global summary of 36.72 seconds:
100.0% 2526 Received ticks


piotr

--

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

import static java.lang.System.out;

public class ArrayFillTest {

private static void rangeCheck(int arrayLen, int fromIndex, int
toIndex) {


if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex+")");
if (fromIndex < 0)
throw new ArrayIndexOutOfBoundsException(fromIndex);

if (toIndex > arrayLen)
throw new ArrayIndexOutOfBoundsException(toIndex);
}
public static void fill(Object[] a, Object val) {
fill(a, 0, a.length, val);
}


public static void fill(Object[] a, int fromIndex, int toIndex,
Object val) {

rangeCheck(a.length, fromIndex, toIndex);

final int size = toIndex - fromIndex;
final int threshold = size < 24 ? size :
(size < 48 ? ((size >> 1) + (size & 1)) : 16);

int s = 0;
for(; s < threshold; ++s)
a[fromIndex + s] = val;
for(; s <= size - s; s <<= 1)
System.arraycopy(a, fromIndex, a, fromIndex + s, s);
if (s < size)
System.arraycopy(a, fromIndex, a, fromIndex + s, size - s);
}

public static void main(String[] args) {
int size = Integer.parseInt(args[0]);
int loops = Integer.parseInt(args[1]);
int trys = Integer.parseInt(args[2]);

Object[] a = new Object[size];

fill(a, "0");
for(Object o : a)
assert o == "0";
fill(a, "1");
for(Object o : a)
assert o == "1";

long t;
ArrayList<Long> t0s = new ArrayList<Long>();
ArrayList<Long> t1s = new ArrayList<Long>();

for(int n = 0; n < trys; ++n) {
t = System.currentTimeMillis();
for(int i = 0; i < loops; ++i) {
Arrays.fill(a, "0");
Arrays.fill(a, "1");
}
t = System.currentTimeMillis() - t;
out.println("t0: "+ t);
t0s.add(t);

t = System.currentTimeMillis();
for(int i = 0; i < loops; ++i) {
fill(a, "0");
fill(a, "1");
}
t = System.currentTimeMillis() - t;
out.println("t1: "+ t);
t1s.add(t);
}

out.printf("args: size=%d, loops=%d, trys=%d\n",
size, loops, trys);

t = 0;
for(Long l : t0s) t += l;
long avg_t0 = t/trys;
out.printf("t0 avg: %d (min/max: %d/%d)\n",
avg_t0, min(t0s), max(t0s));

t = 0;
for(Long l : t1s) t += l;
long avg_t1 = t/trys;
out.printf("t1 avg: %d (min/max: %d/%d)\n",
avg_t1, min(t1s), max(t1s));

out.printf("t0/t1%%: %.2f%%\n",
(double)avg_t0/avg_t1*100);
}
}

Piotr Kobzda

unread,
Apr 26, 2005, 8:10:56 AM4/26/05
to
... troszkę za dużo wyciąłem z załączonego źródła i się nie skompiluje,
min() i max() są oczywiście z Collections (przykład metod, których nie
należy raczej polecać do statycznych importów .... choć kto je tam w
sumie wie?... ;) ).


piotr

Piotr Lipson

unread,
Apr 26, 2005, 1:17:25 PM4/26/05
to
Piotr Kobzda wrote:
>
> Piotr Lipson wrote:
>
>> U mnie jest ta twoja metoda jakies 4 razy szybsza... ale opcja
>> "-server" powoduje ze twoja jest szybsza o 12%.
>
>
> Hmmm... u mnie opcja -server nie zmienia aż tak drastycznie osiągów
> Arrays.fill().
>
> Może próbowałeś z wcześniejszą Javą ? ... w 'piątce' poprawiono
> wydajność, m.in. właśnie System.arraycopy() (choć tu akurat nie więcej
> niż 10%) ...
>
> Mógłbyś może podać wyniki testów podobnych moim (źródło na końcu) ?
> Jeśli komuś wskaźnik 't0/t1%' znacznie odbiega od podanych tutaj, to gdy
> poinformować tu o wynikach swych zechce, także mile widzianym będzie.
>

Ja napisalem sobie cos takiego, nie tak ogolne jak twoje.
Po dodaniu rozbiegówki to z opcja "-server" Arrays.fill() jest nawet
mikroskopijnie szybsze. Wyniki tego i twojego testu podam w nastepnym
poscie.

package test;
import java.util.Arrays;
public class Test {

public static void main(String[] args) throws Exception{
Object[] arr=new Object[1<<16];
//rozbiegówka
for(int i=0;i<10000;i++){
Test.fill(arr,0,arr.length,Test.class);
}
for(int i=0;i<10000;i++){
Arrays.fill(arr,0,arr.length,Test.class);
}
//prawdziwy test
long time=System.nanoTime();
for(int i=0;i<10000;i++){
Arrays.fill(arr,0,arr.length,Test.class);
}
System.out.println(System.nanoTime()-time);
time=System.nanoTime();
for(int i=0;i<10000;i++){
Test.fill(arr,0,arr.length,Test.class);
}
System.out.println(System.nanoTime()-time);

}

public static void fill(Object[] a, int fromIndex, int toIndex, Object
val) {

if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex+")");
if (fromIndex < 0)
throw new ArrayIndexOutOfBoundsException(fromIndex);

if (toIndex > a.length)
throw new ArrayIndexOutOfBoundsException(toIndex);

Piotr Lipson

unread,
Apr 26, 2005, 1:29:13 PM4/26/05
to
Wyniki ponizej, widac ze serer sie calkiem sprawnie rozgrzewa. Najpierw
moje java -version:

java version "1.5.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09)
Java HotSpot(TM) Server VM (build 1.5.0_02-b09, mixed mode)

AMD Athlon 64 3400+ (2200) 512 DDR333 WinXP HE

w moim tescie:

(pierwsze Arrays.fill() czas w nano)


5228906188
1248224286

z opcja server:

1160008605
1164233722

W twoim (10000 5000 10):

t0: 781
t1: 156
t0: 797
t1: 141
t0: 797
t1: 140
t0: 797
t1: 156
t0: 782
t1: 156
t0: 781
t1: 156
t0: 782
t1: 140
t0: 797
t1: 141
t0: 812
t1: 157
t0: 812
t1: 156
args: size=10000, loops=5000, trys=10
t0 avg: 793 (min/max: 781/812)
t1 avg: 149 (min/max: 140/157)
t0/t1%: 532,21%

z opcja server:

t0: 719
t1: 188
t0: 703
t1: 156
t0: 313
t1: 156
t0: 156
t1: 156
t0: 157
t1: 140
t0: 156
t1: 157
t0: 156
t1: 156
t0: 156
t1: 141
t0: 156
t1: 157
t0: 156
t1: 156
args: size=10000, loops=5000, trys=10
t0 avg: 282 (min/max: 156/719)
t1 avg: 156 (min/max: 140/188)
t0/t1%: 180,77%

Piotr Lipson

unread,
Apr 26, 2005, 1:36:19 PM4/26/05
to
przy użyciu 1.4.2_07 mam takie wyniki w moim tescie:

(czas w milisekundach, pierwsze Arrays.fill())

4953
1109

z -server

1344
1109

Piotr Kobzda

unread,
Apr 26, 2005, 7:00:41 PM4/26/05
to

Piotr Lipson wrote:
[...]

I jeszcze trochę wyników, tym razem dla:

Windows 95, Duron 800, 128M RAMu

---

java version "1.5.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09)
Java HotSpot(TM) Client VM (build 1.5.0_02-b09, mixed mode)


args: size=10000, loops=5000, trys=10
t0 avg: 2307 (min/max: 2300/2310)
t1 avg: 440 (min/max: 380/500)
t0/t1%: 524,32%

args: size=65536, loops=200, trys=10
t0 avg: 1021 (min/max: 990/1050)
t1 avg: 665 (min/max: 660/710)
t0/t1%: 153,53%

28569389362
16588386496


i to samo z opcją -server:

args: size=10000, loops=5000, trys=10
t0 avg: 1147 (min/max: 820/2200)
t1 avg: 440 (min/max: 390/500)
t0/t1%: 260,68%

args: size=65536, loops=200, trys=10
t0 avg: 989 (min/max: 940/1040)
t1 avg: 675 (min/max: 660/710)
t0/t1%: 146,52%

17401712232
16633976433


---

java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)


args: size=10000, loops=5000, trys=10
t0 avg: 2164 (min/max: 2140/2200)
t1 avg: 445 (min/max: 430/500)
t0/t1%: 486.29213483146066

args: size=65536, loops=200, trys=10
t0 avg: 989 (min/max: 980/990)
t1 avg: 658 (min/max: 650/660)
t0/t1%: 150.30395136778117

24450
16470


i z opcją -server:

args: size=10000, loops=5000, trys=10
t0 avg: 1413 (min/max: 990/3520)
t1 avg: 444 (min/max: 380/540)
t0/t1%: 318.2432432432432

args: size=65536, loops=200, trys=10
t0 avg: 1125 (min/max: 1090/1210)
t1 avg: 643 (min/max: 600/770)
t0/t1%: 174.96111975116642

17310
15270


Czyli, jak widać, bywa to różnie... nigdy jednak na korzyść
Arrays.fill() ...
Jednego tylko jeszcze tu nie rozumiem, czemu nasze testy, różnią się tak
istotnie i to tylko w przypadku opcji -server --- mój test dla
size=65536 jest bardzo zbliżony do Twojego (bliższy jeszcze byłby z
loops=5000, z 200 wychodzi jednak podobnie...) -- umie ktoś może to
wyjaśnić ?


piotr

Piotr Lipson

unread,
Apr 27, 2005, 4:33:43 PM4/27/05
to
Piotr Kobzda wrote:

> Czyli, jak widać, bywa to różnie... nigdy jednak na korzyść
> Arrays.fill() ...
> Jednego tylko jeszcze tu nie rozumiem, czemu nasze testy, różnią się tak
> istotnie i to tylko w przypadku opcji -server --- mój test dla
> size=65536 jest bardzo zbliżony do Twojego (bliższy jeszcze byłby z
> loops=5000, z 200 wychodzi jednak podobnie...) -- umie ktoś może to
> wyjaśnić ?


Obstawialbym ze jest to tych kilka instrukcji SSE któregostam ktorymi
nasze procki sie roznia, moze to byc kwestia innej architekury
procka/systemu i "dopasowania" kompilatora w JVM do architekrury, ale
ciezko powiedziec, moze jakbys dal dluzsza rozbiegowke to Arrays.fill()
by wygralo tak jak u mnie, ale ciezko powiedziec.

0 new messages