Why doesn't Java have true multidimensional arrays? -
Why doesn't Java have true multidimensional arrays? -
the tl;dr version, don't want background, next specific question:
questionwhy doesn't java have implementation of true multidimensional arrays? there solid technical reason? missing here?
backgroundjava has multidimensional arrays @ syntax level, in 1 can declare
int[][] arr = new int[10][10];
but seems not 1 might have expected. rather having jvm allocate contiguous block of ram big plenty store 100 int
s, comes out array of arrays of int
s: each layer contiguous block of ram, thing whole not. accessing arr[i][j]
rather slow: jvm has to
int[]
stored @ arr[i]
; index find int
stored @ arr[i][j]
. this involves querying object go 1 layer next, rather expensive.
why java thisat 1 level, it's not hard see why can't optimised simple scale-and-add lookup if allocated in 1 fixed block. problem arr[3]
reference of own, , can changed. although arrays of fixed size, write
arr[3] = new int[11];
and scale-and-add screwed because layer has grown. you'd need know @ runtime whether still same size used be. in addition, of course, allocated somewhere else in ram (it'll have be, since it's bigger it's replacing), it's not in right place scale-and-add.
what's problematic itit seems me not ideal, , 2 reasons.
for one, it's slow. test ran these methods summing contents of single dimensional or multidimensional array took nearly twice long (714 seconds vs 371 seconds) multidimensional case (an int[1000000]
, int[100][100][100]
respectively, filled random int
values, run 1000000 times warm cache).
public static long sumsingle(int[] arr) { long total = 0; (int i=0; i<arr.length; i++) total+=arr[i]; homecoming total; } public static long summulti(int[][][] arr) { long total = 0; (int i=0; i<arr.length; i++) (int j=0; j<arr[0].length; j++) (int k=0; k<arr[0][0].length; k++) total+=arr[i][j][k]; homecoming total; }
secondly, because it's slow, thereby encourages obscure coding. if encounter performance-critical naturally done multidimensional array, have incentive write flat array, if makes unnatural , hard read. you're left unpalatable choice: obscure code or slow code.
what done itit seems me basic problem plenty fixed. reason, saw earlier, can't optimised construction might change. java has mechanism making references unchangeable: declare them final
.
now, declaring with
final int[][] arr = new int[10][10];
isn't plenty because it's arr
final
here: arr[3]
still isn't, , changed, construction might still change. if had way of declaring things final
throughout, except @ bottom layer int
values stored, we'd have entire immutable structure, , allocated 1 block, , indexed scale-and-add.
how syntactically, i'm not sure (i'm not language designer). maybe
final int[final][] arr = new int[10][10];
although admittedly looks bit weird. mean: final
@ top layer; final
@ next layer; not final
@ bottom layer (else int
values immutable).
finality throughout enable jit compiler optimise give performance of single dimensional array, take away temptation code way round slowness of multidimensional arrays.
(i hear rumour c# this, although hear rumour clr implementation bad it's not worth having... perhaps they're rumours...)
questionso why doesn't java have implementation of true multidimensional arrays? there solid technical reason? missing here?
updatea bizarre side note: difference in timings drops away few percent if utilize int
running total rather long
. why there such little difference int
, , such big difference long
?
code used benchmarking, in case wants seek reproduce these results:
public class multidimensional { public static long sumsingle(final int[] arr) { long total = 0; (int i=0; i<arr.length; i++) total+=arr[i]; homecoming total; } public static long summulti(final int[][][] arr) { long total = 0; (int i=0; i<arr.length; i++) (int j=0; j<arr[0].length; j++) (int k=0; k<arr[0][0].length; k++) total+=arr[i][j][k]; homecoming total; } public static void main(string[] args) { final int iterations = 1000000; random r = new random(); int[] arr = new int[1000000]; (int i=0; i<arr.length; i++) arr[i]=r.nextint(); long total = 0; system.out.println(sumsingle(arr)); long time = system.nanotime(); (int i=0; i<iterations; i++) total = sumsingle(arr); time = system.nanotime()-time; system.out.printf("took %d ms single dimension\n", time/1000000, total); int[][][] arrmulti = new int[100][100][100]; (int i=0; i<arrmulti.length; i++) (int j=0; j<arrmulti[i].length; j++) (int k=0; k<arrmulti[i][j].length; k++) arrmulti[i][j][k]=r.nextint(); system.out.println(summulti(arrmulti)); time = system.nanotime(); (int i=0; i<iterations; i++) total = summulti(arrmulti); time = system.nanotime()-time; system.out.printf("took %d ms multi dimension\n", time/1000000, total); } }
but seems not 1 might have expected.
why?
consider form t[]
means "array of type t", expect int[]
mean "array of type int", expect int[][]
mean "array of type array of type int", because there's no less reason having int[]
t
int
.
as such, considering 1 can have arrays of type, follows way [
, ]
used in declaring , initialising arrays (and matter, {
, }
, ,
), without sort of special rule banning arrays of arrays, sort of utilize "for free".
now consider there things can jagged arrays can't otherwise:
we can have "jagged" arrays different inner arrays of different sizes. we can have null arrays within outer array appropriate mapping of data, or perhaps allow lazy building. we can deliberately alias within array e.g.lookup[1]
same array lookup[5]
. (this can allow massive savings data-sets, e.g. many unicode properties can mapped total set of 1,112,064 code points in little amount of memory because leaf arrays of properties can repeated ranges matching patterns). some heap implementations can handle many smaller objects improve 1 big object in memory. there cases these sort of multi-dimensional arrays useful.
now, default state of feature unspecified , unimplemented. needs decide specify , implement feature, or else wouldn't exist.
since, shown above, array-of-array sort of multidimensional array exist unless decided introduce special banning array-of-array feature. since arrays of arrays useful reasons above, unusual decision make.
conversely, sort of multidimensional array array has defined rank can greater 1 , used set of indices rather single index, not follow naturally defined. need to:
decide on specification declaration, initialisation , utilize work. document it. write actual code this. test code this. handle bugs, edge-cases, reports of bugs aren't bugs, backward-compatibility issues caused fixing bugs.also users have larn new feature.
so, has worth it. things create worth be:
if there no way of doing same thing. if way of doing same thing unusual or not well-known. people expect similar contexts. users can't provide similar functionality themselves.in case though:
but there is. using strides within arrays known c , c++ programmers , java built on syntax same techniques straight applicable java's syntax based on c++, , c++ has direct back upwards multidimensional arrays arrays-of-arrays. (except when statically allocated, that's not have analogy in java arrays objects). one can write class wraps array , details of stride-sizes , allows access via set of indices.really, question not "why doesn't java have true multidimensional arrays"? "why should it?"
of course, points made in favour of multidimensional arrays valid, , languages have them reason, burden nonetheless argue feature in, not argue out.
(i hear rumour c# this, although hear rumour clr implementation bad it's not worth having... perhaps they're rumours...)
like many rumours, there's element of truth here, not total truth.
.net arrays can indeed have multiple ranks. not way in more flexible java. each rank can have lower-bound other zero. such, illustration have array goes -3 42 or 2 dimensional array 1 rank goes -2 5 , 57 100, or whatever.
c# not give finish access of built-in syntax (you need phone call array.createinstance()
lower bounds other zero), allow utilize syntax int[,]
two-dimensional array of int
, int[,,]
three-dimensional array, , on.
now, work involved in dealing lower bounds other 0 adds performance burden, , yet these cases relatively uncommon. reason single-rank arrays lower-bound of 0 treated special case more performant implementation. indeed, internally different sort of structure.
in .net multi-dimensional arrays lower bounds of 0 treated multi-dimensional arrays lower bounds happen 0 (that is, illustration of slower case) rather faster case beingness able handle ranks greater 1.
of course, .net could have had fast-path case zero-based multi-dimensional arrays, reasons java not having them apply and fact there's 1 special case, , special cases suck, , there 2 special cases , suck more. (as is, 1 can have issues trying assign value of 1 type variable of other type).
not single thing above shows java couldn't perchance have had sort of multi-dimensional array talk of; have been sensible plenty decision, decision made sensible.
java arrays performance multidimensional-array
Comments
Post a Comment