Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!eternal-september.org!feeder.eternal-september.org!.POSTED!not-for-mail From: Eric Sosman Newsgroups: comp.lang.java.programmer Subject: Re: Bulk Array Element Allocation, is it faster? Date: Sun, 25 Sep 2011 17:48:18 -0400 Organization: A noiseless patient Spider Lines: 107 Message-ID: References: <9e8fplF19bU1@mid.individual.net> <9e8kdhF6lmU1@mid.individual.net> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Sun, 25 Sep 2011 21:48:55 +0000 (UTC) Injection-Info: mx04.eternal-september.org; posting-host="f8igmItKsWs6nM5YanFxAA"; logging-data="2166"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18Uz3X3fAwUN9Az4jobXOK1" User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:6.0.2) Gecko/20110902 Thunderbird/6.0.2 In-Reply-To: Cancel-Lock: sha1:U/d8UaatQfuQc6YiZ5D54cb9Ih0= Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:8313 On 9/25/2011 11:14 AM, Jan Burse wrote: > Eric Sosman schrieb: >> Again, I point out that the bulk and lazy variants do not do >> the same thing. Consider, for example >> >> class Bla { >> private static int master_seqno = 0; >> public final int seqno = ++master_seqno; >> } >> >> Observe that the value of bla[42].seqno differs between the two >> variants; it would therefore be an error to "optimize" either by >> transforming it into the other. > > Not really. You could only see a difference in the order > that Bla() gets a number. You'll also see a difference in *which* number bla[42] gets. In the bulk initialization, bla[42].seqno is 43, always. With lazy initialization, it can be anything at all between 1 and n inclusive. QED, and your "not really" makes no sense to me. There are lots of other effects Bla() construction might have that would turn out differently in bulk or lazy initialization. If the constructor writes a message to System.out, all the messages will appear together in bulk initialization, but will be scattered all over the place with lazy initialization. If the constructor throws an exception -- even a seldom-caught RuntimeException -- the exceptions will appear in a different order w.r.t. other actions in the program. The two code sequences are irreconcilably different. > So if your application does not depend on the order > the seqno's are created there is no functional problem. From the application's point of view perhaps not. But Java and the JVM can't possibly know that; they follow the orders you give. You say "Assign this seqno (not that one) to the new Bla, and throw (or don't throw) this exception, write (or don't write) this output, and do (or don't do) all these things in their proper order w.r.t. all my other commands." Concrete example: In a sense you do not care what value Math.random() returns, but Java is contractually bound to deliver a specific value under specific circumstances, and cannot violate its contract even if you are in a forgiving mood. > Main question I have here is not about relative > correctness of bulk versus lazy. But why bulk is > counterintuitively much faster? Nobody knows, because you've shown no code. My first guess (already hinted at) is that your timing is faulty; it is notoriously hard to get good timings even from statically-bound languages these days, and even more difficult with dynamically-bound partially- interpreted-partially-compiled garbage-collected multi-threaded languages like Java. I'm sticking with that guess until you show some evidence to refute it. > Since the bulk is much faster I am assuming [...] Yeah. > Actually this loop is something that shocked me > when I started working with Java many years ago. > What there is no way to make a "new" of an array > with all its elements? That's another topic, and one that's been hashed over several times in other threads. The principal reason, I think, is that it would so seldom be useful to create an array of N objects *all* created by the no-args constructor: Who needs N copies of "the same" thing? And what if the class has no no-args constructor? Okay, sure, it could happen occasionally. But often enough to justify a special feature in the language, with special rules for "What if I want to pass arguments to the constructors?" or "What if the constructor is inaccessible and I'm supposed to use a factory method?" and "What if I *don't* want objects created yet?" and so on, and so on? Challenge: Look through your own code, right now, and count the number of times you have actually filled an array with references to N identically-constructed-with-no-args objects. In other words, count the number of times your own actual code would have been able to take advantage of such a feature if Java provided it. > This is not seen if one works with int[] or > double[] arrays. But as soon as you work with some > other array, either a higher dimensional of int[] > or double[] or an array of some class X. You are > responsible for populating the elements. How often do you create an int[] and leave all its elements alone, still holding their original zeroes? (On purpose, I mean.) In any case, Java *does* populate the array for you: With null references. Do you have a prejudice against `null'? > I am > not interessted in a general theory between going > from bulk to lazy and back and forth. Forget > about the lazy and explain the bulk! Exhibit some actual code, so people can stop guessing about what you've done. -- Eric Sosman esosman@ieee-dot-org.invalid