Faster session date handling (partially solves #415) #418

Merged
merged 2 commits into from Dec 26, 2012

Conversation

Projects
None yet
3 participants
@meteficha
Owner

meteficha commented Sep 5, 2012

The first commit, 065e33a, breaks the cookie format. Other than that, I feel it should be accepted.

The second commit, b2a9beb, is somewhat more controversial. We'll need a major version bump of yesod-core. It's also a bit complicated.

meteficha added some commits Sep 5, 2012

Faster, leaner implementation of putTime/getTime.
Benchmark on my computer (per call, includes runPut/runGet):

    old putTime: 5658 ns +/- 224ns
    new putTime:  821 ns +/-  24ns (7x faster)

    old getTime: 7228 ns +/- 126ns
    new getTime:   99 ns +/-   4ns (73x faster!!)

Besides, the old format used 25 raw bytes (33.3 bytes on the
base64 output), while the new one uses 8 bytes (10.6 bytes on the
base64 output).
Use a cache for session cookie's expiration time.
The following HelloWorld app was used as benchmark:

  data HelloWorld = HelloWorld
  mkYesod "HelloWorld" [parseRoutes|
    / HomeR GET
  |]

  instance Yesod HelloWorld where
    -- makeSessionBackend = const $ return Nothing

  getHomeR = return . RepPlain . toContent $ "Hello World!"

  main :: IO ()
  main = warp 8080 HelloWorld

The benchmark was tested with httperf under the following
environments:

  [vanilla-nosession] Released yesod-core 1.1.1.1, but without sessions.

  [vanilla-session] Released yesod-core 1.1.1.1 (with sessions).

  [faster-session-1] With patch 065e33a, "Faster, leaner
  implementation of putTime/getTime".

  [faster-session-2] With this commit.

Performance results:

  A) Testing with:
       httperf --hog --client=0/1 --server=localhost \
               --port=8080 --uri=/ --rate=1000 \
               --send-buffer=4096 --recv-buffer=16384 \
               --num-conns=100 --wsess=1000,60,1 \
               --burst-length=20 --session-cookie

     Results:
       vanilla-nosession: 19187.7 req/s (0.1 ms/req)
       vanilla-session:    2523.3 req/s (0.4 ms/req)
       faster-session-1:   2933.5 req/s (0.3 ms/req)
       faster-session-2:   2957.5 req/s (0.3 ms/req)

     This test benchmarks both saving and loading the session.
     Interestingly, this commit provides only a small performance
     increase.

  B) Testing with:
       httperf --hog --client=0/1 --server=localhost \
               --port=8080 --uri=/ --rate=1000 \
               --send-buffer=4096 --recv-buffer=16384 \
               --num-conns=100 --num-calls=1000 \
               --burst-length=20

     Results:
       vanilla-nosession: 43548.7 req/s (0.0 ms/req)
       vanilla-session:    3609.4 req/s (0.3 ms/req)
       faster-session-1:   3454.9 req/s (0.3 ms/req)
       faster-session-2:   3786.9 req/s (0.3 ms/req)

     This test benchmarks only saving the session.  Strangely,
     faster-session-1 was worse than vanilla-session (while
     isolated tests show that the new putTime should be +70x
     faster).  However, there is a non-negligible performance
     increase on faster-session-2.

@meteficha meteficha referenced this pull request Sep 5, 2012

Closed

session slowness #415

@lbolla

This comment has been minimized.

Show comment Hide comment
@lbolla

lbolla Sep 5, 2012

Contributor

Shouldn't there be any "regression" testing to make sure that the new implementation works as expected?

Contributor

lbolla commented Sep 5, 2012

Shouldn't there be any "regression" testing to make sure that the new implementation works as expected?

@snoyberg

This comment has been minimized.

Show comment Hide comment
@snoyberg

snoyberg Sep 5, 2012

Owner

It seems like the only breaking changes are to the signatures for the functions:

  • loadClientSession
  • clientSessionBackend

Would it be theoretically possible to keep the old versions of those functions available with a DEPRECATED pragma, and keep your improved versions with a different name? Then we can just change the default behavior to use the new functions, and update in the next major release.

Owner

snoyberg commented Sep 5, 2012

It seems like the only breaking changes are to the signatures for the functions:

  • loadClientSession
  • clientSessionBackend

Would it be theoretically possible to keep the old versions of those functions available with a DEPRECATED pragma, and keep your improved versions with a different name? Then we can just change the default behavior to use the new functions, and update in the next major release.

@snoyberg snoyberg merged commit b2a9beb into yesodweb:master Dec 26, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment