JESS: Performance, Java static method vs Java oject method calls.

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

JESS: Performance, Java static method vs Java oject method calls.

Nguyen, Son
Performance, Java static method vs Java oject method calls.

Hi,

I observed a real dramatic difference in performace when using the following two ways to get the same result.

(bind ?value (?stringObject codePointAt 0))
(bind ?value (Helper.stringCodePointAt ?stringObject 0))

I did some not so scientific measurements with the following clp:

(deftemplate model1 (slot a)(slot b))
(deftemplate model2 (slot a)(slot b))

(import Helper)

(deffunction test1 (?string)
        (bind ?start (System.nanoTime))
        (bind ?var (?string codePointAt 0))
        (bind ?stop (System.nanoTime))
        (printout t ">> test1 took in nanosec: " (- ?stop ?start) crlf)
)

(deffunction test2 (?string)
        (bind ?start (System.nanoTime))
        (bind ?var (Helper.stringCodePointAt ?string 0))
        (bind ?stop (System.nanoTime))
        (printout t "-- test2 took in nanosec: " (- ?stop ?start) crlf)
)

(deffunction compare (?s1 ?s2 ?message)
        ;(printout t ?s1 ":" ?s2 " - called by " ?message " returns " (eq ?s1 ?s2) crlf)
        (if (eq ?s1 ?s2) then
                (test1 a)
                (test2 a))
        (return (eq ?s1 ?s2)))

(defrule rule1
        (model1(a ?model1a &:(compare ?model1a a "model1 slot a"))(b ?model1b &:(compare ?model1b b "rule1 model1 slot b")))

        (model2(a ?model2a &:(compare ?model2a 1 "model2 slot a"))(b ?model2b &:(compare ?model2b 2 "rule1 model2 slot b")))

        (test (compare a a a))
        =>
)

………………

(defrule rule16
        (model1(a ?model1a &:(compare ?model1a a "model1 slot a"))(b ?model1b &:(compare ?model1b b "rule16 model1 slot b")))

        (model2(a ?model2a &:(compare ?model2a 1 "model2 slot a"))(b ?model2b &:(compare ?model2b 2 "rule16 model2 slot b")))

        (test (compare a a a))
        =>
)

(assert (model2 (a 1)(b 2)))
(assert (model1 (a a)(b b)))

The difference drastic in favor of the static implementation. The times are in the 30 to 40 microseconds while the other calls take much longer, usually in the 1000 to 2000 microseconds.

Without rules, the difference is barely noticable.
The side effect of the performance drop has a significant impact of scalability in a multi-cpu system.
In our test environment, using Jmeter with multiple virtual users, the cpu usage of a 4 CPU system barely reach the 40% mark with the 'slow' method.

With the static implementation, it can go up to the mid 90s for cpu  usage.

Any feedback is appreciated.


Son Nguyen




Reply | Threaded
Open this post in threaded view
|

JESS: RE: Performance, Java static method vs Java oject method calls.

Friedman-Hill, Ernest
The time difference you're looking at is the time it takes the JVM to throw an exception. Jess interprets an expression like this
 
(?string codePointAt 0)
 
as (assuming ?string is the symbol 'a')

(call a codePointAt 0)

That's actually ambiguous. We might be calling a static method codePointAt on a class named a, or we might want to call the method codePointAt on the String "a". Since it's a SYMBOL, Jess assumes the first case is more likely. The first step in trying the first alternative is to try to load the class 'a'. If we do it and fail, it costs us a ClassNotFoundException. Then we can try plan 'B', which is to call the member method on the String.

But that's only what Jess does if ?string is a SYMBOL. If it's an RU.STRING -- i.e., if it appears in the source as a double-quoted String -- then Jess tries the other alternative first. In this case, that turns out to be the right alternative, and we don't need to pay the cost of throwing the exception. I tried changing all the bare 'a's to "a"s in your source -- the time discrepancy completely disappeared.


________________________________

        From: [hidden email] [mailto:[hidden email]] On Behalf Of Nguyen, Son
        Sent: Friday, October 21, 2011 5:14 PM
        To: jess-users
        Subject: JESS: Performance, Java static method vs Java oject method calls.
       
       


        Hi,

        I observed a real dramatic difference in performace when using the following two ways to get the same result.

        (bind ?value (?stringObject codePointAt 0))
        (bind ?value (Helper.stringCodePointAt ?stringObject 0))

        I did some not so scientific measurements with the following clp:

        (deftemplate model1 (slot a)(slot b))
        (deftemplate model2 (slot a)(slot b))

        (import Helper)

        (deffunction test1 (?string)
                (bind ?start (System.nanoTime))
                (bind ?var (?string codePointAt 0))
                (bind ?stop (System.nanoTime))
                (printout t ">> test1 took in nanosec: " (- ?stop ?start) crlf)
        )

        (deffunction test2 (?string)
                (bind ?start (System.nanoTime))
                (bind ?var (Helper.stringCodePointAt ?string 0))
                (bind ?stop (System.nanoTime))
                (printout t "-- test2 took in nanosec: " (- ?stop ?start) crlf)
        )

        (deffunction compare (?s1 ?s2 ?message)
                ;(printout t ?s1 ":" ?s2 " - called by " ?message " returns " (eq ?s1 ?s2) crlf)
                (if (eq ?s1 ?s2) then
                        (test1 a)
                        (test2 a))
                (return (eq ?s1 ?s2)))

        (defrule rule1
                (model1(a ?model1a &:(compare ?model1a a "model1 slot a"))(b ?model1b &:(compare ?model1b b "rule1 model1 slot b")))

                (model2(a ?model2a &:(compare ?model2a 1 "model2 slot a"))(b ?model2b &:(compare ?model2b 2 "rule1 model2 slot b")))

                (test (compare a a a))
                =>
        )

        ..................

        (defrule rule16
                (model1(a ?model1a &:(compare ?model1a a "model1 slot a"))(b ?model1b &:(compare ?model1b b "rule16 model1 slot b")))

                (model2(a ?model2a &:(compare ?model2a 1 "model2 slot a"))(b ?model2b &:(compare ?model2b 2 "rule16 model2 slot b")))

                (test (compare a a a))
                =>
        )

        (assert (model2 (a 1)(b 2)))
        (assert (model1 (a a)(b b)))

        The difference drastic in favor of the static implementation. The times are in the 30 to 40 microseconds while the other calls take much longer, usually in the 1000 to 2000 microseconds.

        Without rules, the difference is barely noticable.
        The side effect of the performance drop has a significant impact of scalability in a multi-cpu system.
        In our test environment, using Jmeter with multiple virtual users, the cpu usage of a 4 CPU system barely reach the 40% mark with the 'slow' method.

        With the static implementation, it can go up to the mid 90s for cpu  usage.

        Any feedback is appreciated.


        Son Nguyen





--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [hidden email]'
in the BODY of a message to [hidden email], NOT to the list
(use your own address!) List problems? Notify [hidden email].
--------------------------------------------------------------------

Reply | Threaded
Open this post in threaded view
|

RE: JESS: RE: Performance, Java static method vs Java oject method calls.

Nguyen, Son

Hi,

Thanks for the reply. It explains the issue I have with
java.lang.Character as well.

Son Nguyen


-----Original Message-----
From: [hidden email] [mailto:[hidden email]]
On Behalf Of Friedman-Hill, Ernest
Sent: Friday, October 21, 2011 9:33 PM
To: jess-users
Subject: JESS: RE: Performance, Java static method vs Java oject method
calls.

The time difference you're looking at is the time it takes the JVM to
throw an exception. Jess interprets an expression like this
 
(?string codePointAt 0)
 
as (assuming ?string is the symbol 'a')

(call a codePointAt 0)

That's actually ambiguous. We might be calling a static method
codePointAt on a class named a, or we might want to call the method
codePointAt on the String "a". Since it's a SYMBOL, Jess assumes the
first case is more likely. The first step in trying the first
alternative is to try to load the class 'a'. If we do it and fail, it
costs us a ClassNotFoundException. Then we can try plan 'B', which is to
call the member method on the String.

But that's only what Jess does if ?string is a SYMBOL. If it's an
RU.STRING -- i.e., if it appears in the source as a double-quoted String
-- then Jess tries the other alternative first. In this case, that turns
out to be the right alternative, and we don't need to pay the cost of
throwing the exception. I tried changing all the bare 'a's to "a"s in
your source -- the time discrepancy completely disappeared.


________________________________

        From: [hidden email]
[mailto:[hidden email]] On Behalf Of Nguyen, Son
        Sent: Friday, October 21, 2011 5:14 PM
        To: jess-users
        Subject: JESS: Performance, Java static method vs Java oject
method calls.
       
       


        Hi,

        I observed a real dramatic difference in performace when using
the following two ways to get the same result.

        (bind ?value (?stringObject codePointAt 0))
        (bind ?value (Helper.stringCodePointAt ?stringObject 0))

        I did some not so scientific measurements with the following
clp:

        (deftemplate model1 (slot a)(slot b))
        (deftemplate model2 (slot a)(slot b))

        (import Helper)

        (deffunction test1 (?string)
                (bind ?start (System.nanoTime))
                (bind ?var (?string codePointAt 0))
                (bind ?stop (System.nanoTime))
                (printout t ">> test1 took in nanosec: " (- ?stop
?start) crlf)
        )

        (deffunction test2 (?string)
                (bind ?start (System.nanoTime))
                (bind ?var (Helper.stringCodePointAt ?string 0))
                (bind ?stop (System.nanoTime))
                (printout t "-- test2 took in nanosec: " (- ?stop
?start) crlf)
        )

        (deffunction compare (?s1 ?s2 ?message)
                ;(printout t ?s1 ":" ?s2 " - called by " ?message "
returns " (eq ?s1 ?s2) crlf)
                (if (eq ?s1 ?s2) then
                        (test1 a)
                        (test2 a))
                (return (eq ?s1 ?s2)))

        (defrule rule1
                (model1(a ?model1a &:(compare ?model1a a "model1 slot
a"))(b ?model1b &:(compare ?model1b b "rule1 model1 slot b")))

                (model2(a ?model2a &:(compare ?model2a 1 "model2 slot
a"))(b ?model2b &:(compare ?model2b 2 "rule1 model2 slot b")))

                (test (compare a a a))
                =>
        )

        ..................

        (defrule rule16
                (model1(a ?model1a &:(compare ?model1a a "model1 slot
a"))(b ?model1b &:(compare ?model1b b "rule16 model1 slot b")))

                (model2(a ?model2a &:(compare ?model2a 1 "model2 slot
a"))(b ?model2b &:(compare ?model2b 2 "rule16 model2 slot b")))

                (test (compare a a a))
                =>
        )

        (assert (model2 (a 1)(b 2)))
        (assert (model1 (a a)(b b)))

        The difference drastic in favor of the static implementation.
The times are in the 30 to 40 microseconds while the other calls take
much longer, usually in the 1000 to 2000 microseconds.

        Without rules, the difference is barely noticable.
        The side effect of the performance drop has a significant impact
of scalability in a multi-cpu system.
        In our test environment, using Jmeter with multiple virtual
users, the cpu usage of a 4 CPU system barely reach the 40% mark with
the 'slow' method.

        With the static implementation, it can go up to the mid 90s for
cpu  usage.

        Any feedback is appreciated.


        Son Nguyen





--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [hidden email]'
in the BODY of a message to [hidden email], NOT to the list (use
your own address!) List problems? Notify [hidden email].
--------------------------------------------------------------------



--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [hidden email]'
in the BODY of a message to [hidden email], NOT to the list
(use your own address!) List problems? Notify [hidden email].
--------------------------------------------------------------------