The only bug-vector I see in the current predicate approach is that
when used incorrectly it cause the size of methods to explode.  There
are some hard-coded thresholds for the method size in bytecodes that
turn off some or all JIT optimizations; there are also a whole host of
compilation parameters which are optimized with smaller methods in
mind.

Unless someone can offer a great syntactic improvement I recommend
against home-brew frameworks.  Aspects may be able to clean things up
nicely though, I'd be very curious to see some examples.

On Fri, Mar 23, 2012 at 9:56 PM, Zlatin Balevsky <zlat...@gmail.com> wrote:
> Not really.  Here, I'll change my call to allocate everything on one level:
>
>  while (true) {
>              log(" list size is {1} ",
>                new Integer(listToLog.size()));
>          }
>
> I don't see how using this you can log primitive values without garbage.
>
> On Fri, Mar 23, 2012 at 9:33 PM, Ximin Luo <infini...@gmx.com> wrote:
>> That is because in your example you're allocating all those new Object()s in
>> the same stack frame, so the allocator runs out of space on the stack.
>>
>> If you put the call to log(x, new Object()) inside its only function call, 
>> each
>> Object will be destroyed once that call exits, and no GC occurs.
>>
>> Example code here:
>> https://gist.github.com/2177070
>>
>> The "real use case" just adds one simple operation with each logging call
>> (since you're never logging without doing something else as well) to show how
>> little of a difference it makes in real terms (<5%).
>>
>> X
>>
>> On 24/03/12 01:15, Zlatin Balevsky wrote:
>>> You're right, the example you gave will put the arguments on the
>>> stack.  I wanted to clarify Escape Analysis in its current form works
>>> only if a new object doesn't exit the stack frame where it's created.
>>> Because of that, the moment you do something slightly more complicated
>>> you will create garbage like this:
>>>
>>>    private static void logListSize ( final List<?> listToLog ) {
>>>         LOG.log(" list size is {1} ",
>>>                 new Object() {
>>>                         public String toString() {
>>>                                 return String.valueOf(listToLog.size());
>>>                         }
>>>                 });
>>>     }
>>>
>>> Here is the tricky part - if you can guarantee that everywhere in the
>>> jvm the LOG.log method is disabled by the logging system, then the
>>> entire call will compile to noop and no objects will be created.
>>> However, if even one call site enables logging you will end up
>>> creating the temp objects even if they don't get logged.  Below is a
>>> full example, compile and run passing "-verbosegc -XX:+PrintGC" and
>>> watch it GC all the time.
>>>
>>> =====  LazyEvalTest.java ===
>>> import java.util.*;
>>>
>>> public class LazyEvalTest {
>>>
>>>     // only if this is is always false does logging produce no garbage.
>>>     private static boolean shouldLog = true;
>>>
>>>     private static void log(String ar1, Object ar2) {
>>>         if (shouldLog)
>>>              System.out.println(ar1 + ar2.toString());
>>>         shouldLog = false;
>>>     }
>>>
>>>     public static void main(String []ar) {
>>>
>>>         final List<Object> listToLog = new ArrayList<Object>(1000);;
>>>
>>>           while (true) {
>>>               log(" list size is {1} ",
>>>                 new Object() {
>>>                         public String toString() {
>>>                                 return String.valueOf(listToLog.size());
>>>                         }
>>>                 });
>>>           }
>>>     }
>>> }
>>> ======
>>>
>>> As far as garbage collection times go, they are a function of the
>>> count of live objects and on how easy it is to scan them in parallel
>>> and a whole bunch of other factors.  Others can answer better what
>>> values are common for Fred.
>>>
>>> Zlatin
>>>
>>> On Thu, Mar 22, 2012 at 11:47 PM, Ximin Luo <infini...@gmx.com> wrote:
>>>> LOL, are you kidding me?
>>>>
>>>> Please point to the exact lines of code that results in "double-digit
>>>> millisecond pauses"?
>>>>
>>>> Talk is cheap, show us some numbers.
>>>>
>>>> BTW, the "example" I gave is not real code, and contains no variable
>>>> declarations, so your challenge makes no sense. Since you apparently didn't
>>>> understand my implicit argument, here it is in more detail: a typical 
>>>> method
>>>> that computes something simply for the purpose of logging it somewhere, 
>>>> usually
>>>> only allocates local variables that are not stored anywhere in the long 
>>>> term.
>>>> Escape analysis can turn these into stack allocations, saving GC overhead. 
>>>> (If
>>>> they do use more long-term variables, they will need to be stored on the 
>>>> heap,
>>>> but then GC doesn't need to clean these up anyway.)
>>>>
>>>> Why are you even looking at blog entries? Escape analysis has been around 
>>>> for
>>>> years. http://hg.openjdk.java.net/jdk6/jdk6/hotspot/rev/357d4e2eb4dd
>>>>
>>>> On 23/03/12 02:06, Zlatin Balevsky wrote:
>>>>> My claim is based on day-to-day observations of hundreds of JVMs under 
>>>>> various
>>>>> load scenarios.
>>>>>
>>>>> Your claim that modern JVMs "do escape analysis" is worthless as it shows 
>>>>> that
>>>>> you have merely read some blog posts, and even those you've read only
>>>>> partially.  Please point to the exact lines of code in hotspot or any 
>>>>> other
>>>>> modern jvm that will optimize the specific lazy evaluation example you
>>>>> presented, together with the opto-assembly that their JITs produce.  
>>>>> Failing
>>>>> that, take your attitude elsewhere.
>>>>>
>>>>> On Thu, Mar 22, 2012 at 8:49 PM, Ximin Luo <infini...@gmx.com
>>>>> <mailto:infini...@gmx.com>> wrote:
>>>>>
>>>>>     The "drastically cleaner syntax" is a red herring. Most of the time 
>>>>> when you
>>>>>     are doing a complex calculation, you are not going to put it on one 
>>>>> line
>>>>>     anyway. In such cases, the function you are using to do the 
>>>>> calculation might
>>>>>     as well be the toString() method of some object.
>>>>>
>>>>>     Your claim of "double-digit millisecond" pauses is worthless without 
>>>>> some
>>>>>     benchmarking and actual numbers. Modern JVMs do escape analysis to 
>>>>> avoid heap
>>>>>     allocation and this helps especially for transient computations like 
>>>>> in
>>>>>     logging.
>>>>>
>>>>>     On 22/03/12 21:59, Zlatin Balevsky wrote:
>>>>>     > Double-digit millisecond pauses are not nothing.  They may be 
>>>>> acceptable
>>>>>     right
>>>>>     > now but unless you can offer a drastically cleaner syntax Fred 
>>>>> should stick
>>>>>     > with predicates as they are handled much better by the hotspot jit.
>>>>>     >
>>>>>     > On Mar 22, 2012 5:36 PM, "Ximin Luo" <infini...@gmx.com
>>>>>     <mailto:infini...@gmx.com>
>>>>>     > <mailto:infini...@gmx.com <mailto:infini...@gmx.com>>> wrote:
>>>>>     >
>>>>>     >     Lazy evaluation is trivial.
>>>>>     >
>>>>>     >     Log.info("{1} did {2}",
>>>>>     >      new Object(){ public String toString() { return ITEM_1; } },
>>>>>     >      new Object(){ public String toString() { return ITEM_2; } }
>>>>>     >     );
>>>>>     >
>>>>>     >     Garbage collection with short-lived objects costs next to 
>>>>> nothing.
>>>>>     >
>>>>>     >     On 22/03/12 21:15, Zlatin Balevsky wrote:
>>>>>     >     > Constructing the logging strings is half of the problem.  The 
>>>>> amount of
>>>>>     >     garbage
>>>>>     >     > they will generate will result in significantly more time in 
>>>>> garbage
>>>>>     >     collection
>>>>>     >     > pauses.
>>>>>     >     >
>>>>>     >     > Unless you figure out a way to mimic lazy evaluation you have 
>>>>> to live
>>>>>     >     with the
>>>>>     >     > isLoggable predicates.  varargs are not an option either 
>>>>> because
>>>>>     they also
>>>>>     >     > create garbage.
>>>>>     >     >
>>>>>     >     > On Mar 22, 2012 8:11 AM, "Marco Schulze" 
>>>>> <marco.c.schu...@gmail.com
>>>>>     <mailto:marco.c.schu...@gmail.com>
>>>>>     >     <mailto:marco.c.schu...@gmail.com 
>>>>> <mailto:marco.c.schu...@gmail.com>>
>>>>>     >     > <mailto:marco.c.schu...@gmail.com
>>>>>     <mailto:marco.c.schu...@gmail.com> <mailto:marco.c.schu...@gmail.com
>>>>>     <mailto:marco.c.schu...@gmail.com>>>> wrote:
>>>>>     >     >
>>>>>     >     >
>>>>>     >     >
>>>>>     >     >     On 22-03-2012 08:50, Matthew Toseland wrote:
>>>>>     >     >
>>>>>     >     >         On Wednesday 21 Mar 2012 21:18:37 Marco Schulze wrote:
>>>>>     >     >
>>>>>     >     >             There are basically two big concerns regarding 
>>>>> logging
>>>>>     in fred:
>>>>>     >     >
>>>>>     >     >             - Readability and code clutter, which was my 
>>>>> original
>>>>>     >     questioning;
>>>>>     >     >             - Raw throughput, as raised by toad.
>>>>>     >     >
>>>>>     >     >             Point 1 could mostly be solved by removing any 
>>>>> traces of
>>>>>     >     logMINOR and
>>>>>     >     >             logDEBUG on all but the few places where 
>>>>> generating
>>>>>     messages
>>>>>     >     to be
>>>>>     >     >             logged brings noticeable slowdown. That'd be 
>>>>> enough, but,
>>>>>     >     personally,
>>>>>     >     >             the mess that the logging backend is does warrant 
>>>>> a
>>>>>     replacement.
>>>>>     >     >             According to toad, the current system needs
>>>>>     log{MINOR,DEBUG} to
>>>>>     >     >             function
>>>>>     >     >             in a timely manner. Based on this, I think we all 
>>>>> agree a
>>>>>     >     >             replacement is
>>>>>     >     >             desirable.
>>>>>     >     >
>>>>>     >     >             Logging has a few additional requirements:
>>>>>     >     >
>>>>>     >     >             - Log rotation (possibly live);
>>>>>     >     >             - Reentrant;
>>>>>     >     >             - Per-class filtering;
>>>>>     >     >             - Specific information in log (class-name, for 
>>>>> example).
>>>>>     >     >
>>>>>     >     >             Now, _any_ library which fits would make me 
>>>>> happy, as
>>>>>     long as
>>>>>     >     they
>>>>>     >     >             agree
>>>>>     >     >             to two points:
>>>>>     >     >
>>>>>     >     >             - Either lightweight or with optional features. 
>>>>> Else, it
>>>>>     >     would only
>>>>>     >     >             transfer bloat to freenet-ext.jar. For example: 
>>>>> log2socket,
>>>>>     >     config
>>>>>     >     >             management and multiple logging instances;
>>>>>     >     >             - Implementable in a few LoC. Specially, it 
>>>>> shouldn't need
>>>>>     >     specialized
>>>>>     >     >             Formatter and Writer.
>>>>>     >     >
>>>>>     >     >             Plus, it should be fast.
>>>>>     >     >
>>>>>     >     >              From the quick research I made (yep, too many 
>>>>> lists):
>>>>>     >     >
>>>>>     >     >             - SLF4J already fails on point one: it is simply 
>>>>> a wrapper;
>>>>>     >     >             - The Java logging API fails on point two: 
>>>>> specialized
>>>>>     >     classes would
>>>>>     >     >             have to be written to deal with log rotation, 
>>>>> per-class
>>>>>     >     filtering and
>>>>>     >     >             formatting, plus a wrapper for 
>>>>> Logger.{info,warning,...}()
>>>>>     >     methods.
>>>>>     >     >             Exactly the same as a custom logger, with one more
>>>>>     dependency
>>>>>     >     and using
>>>>>     >     >             more LoC;
>>>>>     >     >
>>>>>     >     >         No dependancies, it's part of the JDK, isn't it?
>>>>>     >     >
>>>>>     >     >     More classes need to be loaded at startup. It's just me
>>>>>     thinking too
>>>>>     >     much.
>>>>>     >     >
>>>>>     >     >
>>>>>     >     >         However, if it's not a clearer/simpler API, it 
>>>>> probably
>>>>>     doesn't make
>>>>>     >     >         much sense.
>>>>>     >     >
>>>>>     >     >             - Log4J seems to fail on point one - it only 
>>>>> lacks a button
>>>>>     >     that brings
>>>>>     >     >             back the dead. It seems interesting, and I 
>>>>> haven't dropped
>>>>>     >     this yet.
>>>>>     >     >
>>>>>     >     >             In either case (custom or external), log* would be
>>>>>     banished.
>>>>>     >     Forever.
>>>>>     >     >
>>>>>     >     >         I don't follow. You object to using a separate logs 
>>>>> folder?
>>>>>     >     >
>>>>>     >     >     log* == log{MINOR,DEBUG}, not the logs folder.
>>>>>     >     >     _________________________________________________
>>>>>     >     >     Devl mailing list
>>>>>     >     >     Devl@freenetproject.org <mailto:Devl@freenetproject.org>
>>>>>     <mailto:Devl@freenetproject.org <mailto:Devl@freenetproject.org>>
>>>>>     >     <mailto:Devl@freenetproject.org <mailto:Devl@freenetproject.org>
>>>>>     <mailto:Devl@freenetproject.org <mailto:Devl@freenetproject.org>>>
>>>>>     >     >     
>>>>> https://emu.freenetproject.__org/cgi-bin/mailman/listinfo/__devl
>>>>>     >     >     
>>>>> <https://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl>
>>>>>     >     >
>>>>>     >     >
>>>>>     >     >
>>>>>     >     > _______________________________________________
>>>>>     >     > Devl mailing list
>>>>>     >     > Devl@freenetproject.org <mailto:Devl@freenetproject.org>
>>>>>     <mailto:Devl@freenetproject.org <mailto:Devl@freenetproject.org>>
>>>>>     >     > https://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl
>>>>>     >
>>>>>     >
>>>>>     >     --
>>>>>     >     GPG: 4096R/5FBBDBCE
>>>>>     >     https://github.com/infinity0
>>>>>     >     https://bitbucket.org/infinity0
>>>>>     >     https://launchpad.net/~infinity0 
>>>>> <https://launchpad.net/%7Einfinity0>
>>>>>     >
>>>>>     >
>>>>>     >     _______________________________________________
>>>>>     >     Devl mailing list
>>>>>     >     Devl@freenetproject.org <mailto:Devl@freenetproject.org>
>>>>>     <mailto:Devl@freenetproject.org <mailto:Devl@freenetproject.org>>
>>>>>     >     https://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl
>>>>>     >
>>>>>     >
>>>>>     >
>>>>>     > _______________________________________________
>>>>>     > Devl mailing list
>>>>>     > Devl@freenetproject.org <mailto:Devl@freenetproject.org>
>>>>>     > https://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl
>>>>>
>>>>>
>>>>>     --
>>>>>     GPG: 4096R/5FBBDBCE
>>>>>     https://github.com/infinity0
>>>>>     https://bitbucket.org/infinity0
>>>>>     https://launchpad.net/~infinity0 <https://launchpad.net/%7Einfinity0>
>>>>>
>>>>>
>>>>>     _______________________________________________
>>>>>     Devl mailing list
>>>>>     Devl@freenetproject.org <mailto:Devl@freenetproject.org>
>>>>>     https://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Devl mailing list
>>>>> Devl@freenetproject.org
>>>>> https://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl
>>>>
>>>>
>>>> --
>>>> GPG: 4096R/5FBBDBCE
>>>> https://github.com/infinity0
>>>> https://bitbucket.org/infinity0
>>>> https://launchpad.net/~infinity0
>>>>
>>>>
>>>> _______________________________________________
>>>> Devl mailing list
>>>> Devl@freenetproject.org
>>>> https://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl
>>> _______________________________________________
>>> Devl mailing list
>>> Devl@freenetproject.org
>>> https://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl
>>
>>
>> --
>> GPG: 4096R/5FBBDBCE
>> https://github.com/infinity0
>> https://bitbucket.org/infinity0
>> https://launchpad.net/~infinity0
>>
>>
>> _______________________________________________
>> Devl mailing list
>> Devl@freenetproject.org
>> https://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl
_______________________________________________
Devl mailing list
Devl@freenetproject.org
https://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl

Reply via email to