Oren Eini

aka Ayende Rahien

Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,575
|
Comments: 51,188

Copyright ©️ Ayende Rahien 2004 — 2025

Privacy Policy · Terms
filter by tags archive
stack view grid view
  • architecture (606) rss
  • bugs (450) rss
  • challanges (123) rss
  • community (377) rss
  • databases (481) rss
  • design (893) rss
  • development (640) rss
  • hibernating-practices (71) rss
  • miscellaneous (592) rss
  • performance (397) rss
  • programming (1085) rss
  • raven (1442) rss
  • ravendb.net (526) rss
  • reviews (184) rss
  • 2025
    • May (7)
    • April (10)
    • March (10)
    • February (7)
    • January (12)
  • 2024
    • December (3)
    • November (2)
    • October (1)
    • September (3)
    • August (5)
    • July (10)
    • June (4)
    • May (6)
    • April (2)
    • March (8)
    • February (2)
    • January (14)
  • 2023
    • December (4)
    • October (4)
    • September (6)
    • August (12)
    • July (5)
    • June (15)
    • May (3)
    • April (11)
    • March (5)
    • February (5)
    • January (8)
  • 2022
    • December (5)
    • November (7)
    • October (7)
    • September (9)
    • August (10)
    • July (15)
    • June (12)
    • May (9)
    • April (14)
    • March (15)
    • February (13)
    • January (16)
  • 2021
    • December (23)
    • November (20)
    • October (16)
    • September (6)
    • August (16)
    • July (11)
    • June (16)
    • May (4)
    • April (10)
    • March (11)
    • February (15)
    • January (14)
  • 2020
    • December (10)
    • November (13)
    • October (15)
    • September (6)
    • August (9)
    • July (9)
    • June (17)
    • May (15)
    • April (14)
    • March (21)
    • February (16)
    • January (13)
  • 2019
    • December (17)
    • November (14)
    • October (16)
    • September (10)
    • August (8)
    • July (16)
    • June (11)
    • May (13)
    • April (18)
    • March (12)
    • February (19)
    • January (23)
  • 2018
    • December (15)
    • November (14)
    • October (19)
    • September (18)
    • August (23)
    • July (20)
    • June (20)
    • May (23)
    • April (15)
    • March (23)
    • February (19)
    • January (23)
  • 2017
    • December (21)
    • November (24)
    • October (22)
    • September (21)
    • August (23)
    • July (21)
    • June (24)
    • May (21)
    • April (21)
    • March (23)
    • February (20)
    • January (23)
  • 2016
    • December (17)
    • November (18)
    • October (22)
    • September (18)
    • August (23)
    • July (22)
    • June (17)
    • May (24)
    • April (16)
    • March (16)
    • February (21)
    • January (21)
  • 2015
    • December (5)
    • November (10)
    • October (9)
    • September (17)
    • August (20)
    • July (17)
    • June (4)
    • May (12)
    • April (9)
    • March (8)
    • February (25)
    • January (17)
  • 2014
    • December (22)
    • November (19)
    • October (21)
    • September (37)
    • August (24)
    • July (23)
    • June (13)
    • May (19)
    • April (24)
    • March (23)
    • February (21)
    • January (24)
  • 2013
    • December (23)
    • November (29)
    • October (27)
    • September (26)
    • August (24)
    • July (24)
    • June (23)
    • May (25)
    • April (26)
    • March (24)
    • February (24)
    • January (21)
  • 2012
    • December (19)
    • November (22)
    • October (27)
    • September (24)
    • August (30)
    • July (23)
    • June (25)
    • May (23)
    • April (25)
    • March (25)
    • February (28)
    • January (24)
  • 2011
    • December (17)
    • November (14)
    • October (24)
    • September (28)
    • August (27)
    • July (30)
    • June (19)
    • May (16)
    • April (30)
    • March (23)
    • February (11)
    • January (26)
  • 2010
    • December (29)
    • November (28)
    • October (35)
    • September (33)
    • August (44)
    • July (17)
    • June (20)
    • May (53)
    • April (29)
    • March (35)
    • February (33)
    • January (36)
  • 2009
    • December (37)
    • November (35)
    • October (53)
    • September (60)
    • August (66)
    • July (29)
    • June (24)
    • May (52)
    • April (63)
    • March (35)
    • February (53)
    • January (50)
  • 2008
    • December (58)
    • November (65)
    • October (46)
    • September (48)
    • August (96)
    • July (87)
    • June (45)
    • May (51)
    • April (52)
    • March (70)
    • February (43)
    • January (49)
  • 2007
    • December (100)
    • November (52)
    • October (109)
    • September (68)
    • August (80)
    • July (56)
    • June (150)
    • May (115)
    • April (73)
    • March (124)
    • February (102)
    • January (68)
  • 2006
    • December (95)
    • November (53)
    • October (120)
    • September (57)
    • August (88)
    • July (54)
    • June (103)
    • May (89)
    • April (84)
    • March (143)
    • February (78)
    • January (64)
  • 2005
    • December (70)
    • November (97)
    • October (91)
    • September (61)
    • August (74)
    • July (92)
    • June (100)
    • May (53)
    • April (42)
    • March (41)
    • February (84)
    • January (31)
  • 2004
    • December (49)
    • November (26)
    • October (26)
    • September (6)
    • April (10)
RavenDB - High-Performance NoSQL Document Database
  previous post next post  
May 09 2009

Dense code

time to read 1 min | 30 words

Yes, it is dense, but I also find it beautiful:

image

Tweet Share Share 21 comments

  previous post next post  

Comments

Michael Morton
09 May 2009
08:47 AM
Michael Morton

I agree, very elegant. Never quite occurred to me to do caching in this way, but it does make sense. Definitely something I will have to consider in the future.

JeroenH
09 May 2009
09:41 AM
JeroenH

Personally, I don't really like linq syntactic sugar.

To me, this is just as clear, if not clearer:

queriesLookup.Values

.Select(agg => new QueryAggregationSnapshot

  {

      ...

  }

.Cast <iqueryaggregationsnapshot
.ToArray()

Sasha Goldshtein
09 May 2009
09:44 AM
Sasha Goldshtein

What I don't like is that it's a little difficult to debug. For example, if I wanted to know the value returned by Read() or by Write(), I would have to work quite hard.

When writing a public method such as this one, I often would assign the return values to variables and test the variables explicitly to facilitate debugging.

Chris Martin
09 May 2009
10:08 AM
Chris Martin

Lame...even gay; if you ask me. ;)

Thomas Eyde
09 May 2009
10:43 AM
Thomas Eyde

Too dense for my taste. Too many things happens at once, so I have a hard time figuring out what is going on.

Dave
09 May 2009
11:04 AM
Dave

@Sasha. Outside the function itself it shouldn't matter if the result cam from cache or was freshly created.

I don't know how you write your tests, but I hope you don't started testing cached in the GetReportSnapshot tests. As GetReportSnapshot depends on cached, it's safe to assume cached would work properly as that part is covered elsewhere.

Why would you give the GC a lot of work only so you can when you have a problem set a breakpoint? If you ever would encounter a problem in the GetReportSnapshot method, just add the intermediate (result) variable just for debugging. When you're done debugging, don't forget to remove the variable. With all the tears and layers I have enough overhead performance penalties. I don't need extra penalties.

noone
09 May 2009
13:14 PM
noone

Frankly, I see nothing bug ugly.

Colin Jack
09 May 2009
15:01 PM
Colin Jack

Too dense for me.

Frank Quednau
09 May 2009
15:46 PM
Frank Quednau

What's with the unused "snapshots" variable? You could write

_ => ...

Should look even more dense ;)

And why is the type of "agg" so similar to the QueryAgg..Snapshot type?

Anyway, I like it.

Omer Mor
09 May 2009
16:20 PM
Omer Mor

Do you really need to turn the result into an array ( .ToArray() ) at the end?

Jeremy Gray
09 May 2009
16:40 PM
Jeremy Gray

@Omer - Yes, in order to force evaluation and convert the results into a form that can be safely cached and reused.

Ayende Rahien
09 May 2009
17:25 PM
Ayende Rahien

Frank,

The unused value is the previous value for the item, which allow you to make modifications. It is not used here.

The reason for this is that I want to create an immutable snapshot

Ayende Rahien
09 May 2009
17:26 PM
Ayende Rahien

Omer,

If I wouldn't do that, I would cache the query itself, not the query results

nightshade427
09 May 2009
18:07 PM
nightshade427

Very nice code! I noticed that ever since I started using ruby, my code is starting to look more and more succinct like this in C#. Couldn't the projection be made simpler without the assignments?

Jacob
09 May 2009
20:33 PM
Jacob

I like it. To me it's not about density or beauty, it's about readability. Your example has that (largely due to your formatting and whitespace). Nice.

PandaWood
10 May 2009
07:04 AM
PandaWood

I think it's just right

Martin
11 May 2009
08:31 AM
Martin

Couldn't caching be achieved without the GetReportSnapshot method itself care about the cashing?

Ian Chamberlain
11 May 2009
09:38 AM
Ian Chamberlain

Pity the poor person who has maintain it years from now.

Dense code is bad for testing, bad for understanding and bad for maintenance.

For me this is the opposite of elegance.

Kelly Stuard
11 May 2009
14:33 PM
Kelly Stuard

You're probably going through a fair amount of work to make cached.Read() work without any passed in information. I would see you more as the type of person who would use aspect oriented programming to do:

[Cached]

public IEnumerable <iqueryaggregationshapshot GetReportSnampshot()

and have it do the

cached.Read followed by the wonderfully compact write.

Jeff Brown
11 May 2009
20:23 PM
Jeff Brown

This looks like memoization. Here's my variation on this:

private Memoizer <ireportsnapshot reportSnapshotMemoizer = new Memoizer <ireportsnapshot();

public IReportSnapshot GetReportSnapshot()

{

reportSnapshotMemoizer.Memoize(() =>

{

    // obtain snapshot

    return reportSnapshot;

});

}

Another variation I use in Gallio is a KeyedMemoizer <tkey,> which is basically a simple dictionary-based lazily populated cache.

Jeff Brown
11 May 2009
20:24 PM
Jeff Brown

Doh! I missed a "return" statement in there.

return reportSnapshotMemoizer.Memoize(() => ....);

Comment preview

Comments have been closed on this topic.

Markdown formatting

ESC to close

Markdown turns plain text formatting into fancy HTML formatting.

Phrase Emphasis

*italic*   **bold**
_italic_   __bold__

Links

Inline:

An [example](http://url.com/ "Title")

Reference-style labels (titles are optional):

An [example][id]. Then, anywhere
else in the doc, define the link:
  [id]: http://example.com/  "Title"

Images

Inline (titles are optional):

![alt text](/path/img.jpg "Title")

Reference-style:

![alt text][id]
[id]: /url/to/img.jpg "Title"

Headers

Setext-style:

Header 1
========
Header 2
--------

atx-style (closing #'s are optional):

# Header 1 #
## Header 2 ##
###### Header 6

Lists

Ordered, without paragraphs:

1.  Foo
2.  Bar

Unordered, with paragraphs:

*   A list item.
    With multiple paragraphs.
*   Bar

You can nest them:

*   Abacus
    * answer
*   Bubbles
    1.  bunk
    2.  bupkis
        * BELITTLER
    3. burper
*   Cunning

Blockquotes

> Email-style angle brackets
> are used for blockquotes.
> > And, they can be nested.
> #### Headers in blockquotes
> 
> * You can quote a list.
> * Etc.

Horizontal Rules

Three or more dashes or asterisks:

---
* * *
- - - - 

Manual Line Breaks

End a line with two or more spaces:

Roses are red,   
Violets are blue.

Fenced Code Blocks

Code blocks delimited by 3 or more backticks or tildas:

```
This is a preformatted
code block
```

Header IDs

Set the id of headings with {#<id>} at end of heading line:

## My Heading {#myheading}

Tables

Fruit    |Color
---------|----------
Apples   |Red
Pears	 |Green
Bananas  |Yellow

Definition Lists

Term 1
: Definition 1
Term 2
: Definition 2

Footnotes

Body text with a footnote [^1]
[^1]: Footnote text here

Abbreviations

MDD <- will have title
*[MDD]: MarkdownDeep

 

FUTURE POSTS

  1. Optimizing the cost of clearing a set - about one day from now
  2. Scaling HNSW in RavenDB: Optimizing for inadequate hardware - 3 days from now

There are posts all the way to May 14, 2025

RECENT SERIES

  1. RavenDB News (2):
    02 May 2025 - May 2025
  2. Recording (15):
    30 Apr 2025 - Practical AI Integration with RavenDB
  3. Production Postmortem (52):
    07 Apr 2025 - The race condition in the interlock
  4. RavenDB (13):
    02 Apr 2025 - .NET Aspire integration
  5. RavenDB 7.1 (6):
    18 Mar 2025 - One IO Ring to rule them all
View all series

RECENT COMMENTS

  • But in case you have nullability checks enabled (i.e. `<Nullable>enable</Nullable>`), then you'll have a compiler warning on ...
    By Samyon Ristov on The null check that didn't check for nulls
  • Grok wasn't *wrong*. It only said that `_items` can't be null for the condition to evaluate to `true`, but didn't say anythi...
    By Johannes Egger on The null check that didn't check for nulls
  • When I started enabling NRT, I remember I was initially confused when all variables (for reference types) declared with `var`...
    By riccardo on The null check that didn't check for nulls
  • That is surprising - I think of var as a shorthand that does not affect the final result of the compilation. I wouldn't expec...
    By Chris B on The null check that didn't check for nulls
  • "It is also about as friendly as a monkey with a sore tooth and an alcohol addiction." And I have to clean my monitor.
    By Tim on When racing the Heisenbug, code quality goes out the Windows

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}