DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Immutable Objects Using Record in Java
  • Floyd's Cycle Algorithm for Fraud Detection in Java Systems
  • Merge Multiple PDFs in MuleSoft
  • Scaling Java Microservices to Extreme Performance Using NCache

Trending

  • 7 Technology Waves I’ve Seen in 30 Years of Software — Will AI Be the Next Real Transformation?
  • Implementing Observability in Distributed Systems Using OpenTelemetry
  • 5 Common Security Pitfalls in Serverless Architectures
  • Every Cache Miss Is a Tiny Tax on Your Performance
  1. DZone
  2. Coding
  3. Languages
  4. C# and Java Comparison: The C# Struct Advantage

C# and Java Comparison: The C# Struct Advantage

In this article, we discuss the advantage of C#'s struct when compared to Java's use of classes and Junion to offer a struct-like data structure.

By 
Dang Ngoc Vu user avatar
Dang Ngoc Vu
·
Aug. 27, 19 · Analysis
Likes (7)
Comment
Save
Tweet
Share
14.5K Views

Join the DZone community and get the full member experience.

Join For Free

C# vs. Java and .Net vs. JVM are never-ending wars. Each ecosystem has its own advantages, loyal fans, and success stories. But, I think .NET has a weapon that Java doesn't: C#'s struct.

Java Test Case

I create a naive class with two public fields of type integer.

Java
 
private static class Coords{
  public int x;
  public int y;

  public Coords(int x, int y) {
    this.x = x;
    this.y = y;
  }
}


Then, I create a test case with JMH.

Java
 
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void testLoopAndGetData(BenchMarkState state, Blackhole bh){
  Coords value;
  for(int i = 0; i < state.SIZE;i++) {
    value = state.data[i];
    bh.consume(value.x);
    bh.consume(value.y);
  }
}

@State(Scope.Benchmark)
public static class BenchMarkState {
  @Setup
  public void init() {
    Random r = new Random();
    for(int i = 0; i < SIZE; i++) {
      int nextInt = r.nextInt();
      data[i] = new Coords(nextInt, nextInt);
    }
  }

  public final int SIZE = 5000000;
  public Coords[] data = new Coords[SIZE];
}


Java takes nearly 20ms for each operation, as seen below:

Benchmark     

Mode

Cnt

Score

Error

Units

TestJavaStruct.testLoopAndGetData

avgt

200

19.787

± 0.152

 ms/op


C# Test Case

I run .NET on Ubuntu 16 with .NET Core and MonoDevelop as my IDE. I created a similar structure with the class version of Java.

C#
 
 public struct Coords
    {
        public int x, y;

        public Coords(int p1, int p2)
        {
            x = p1;
            y = p2;
        }
    }


Then, I use BenchmarkDotNet to create a test case.

  
C#
 
  [CoreJob]
    [RPlotExporter, RankColumn]
    public class BenchmarkStruct
    {
        private Coords[] data;
        public int N = 5000000;

        [GlobalSetup]
        public void Setup()
        {
            Random r= new Random(42);
            data = new Coords[N];
            for (int i = 0; i < N; i++)
            {
                data[i] = new Coords(r.Next(), r.Next());
            }
        }

        [Benchmark]
        public int Loop() {
            int a = 0, b = 0;
            for(int i = 0; i < N; i++) {
                a = data[i].x;
                b = data[i].y;
            }
            return a & b;
        }
    }


We can see that .NET performs very well with struct in this scenario.

| Method |     Mean |     Error |    StdDev | Rank |
|------- |---------:|----------:|----------:|-----:|
|   Loop | 3.167 ms | 0.0473 ms | 0.0420 ms |    1 |


A Solution From Java

There is an attempt to "deliver struct types for Java programming language" called Junion. As they described, a struct can save a significant amount of memory when compared with a standard class in Java. It's a very good optimization when you have some arrays with millions of objects. But I was wondering if Junion can provide a solution as fast as a struct in C#.

Declaring a struct with Junion is simple.

C#
 
@Struct
private static class CoordsStruct{
  public int x;
  public int y;
}


Then, the test case with JMH.

Java
 
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void testJunion(BenchMarkState state, Blackhole bh){
  CoordsStruct value;
  for(int i = 0; i < state.SIZE;i++) {
    value = state.dataStruct[i];
    bh.consume(value.x);
    bh.consume(value.y);
  }
}

@State(Scope.Benchmark)
public static class BenchMarkState {
  @Setup
  public void init() {
    Random r = new Random();
    for(int i = 0; i < SIZE; i++) {
      int nextInt = r.nextInt();
      dataStruct[i] = new CoordsStruct();
      dataStruct[i].x = nextInt;
      dataStruct[i].y = nextInt;
    }
  }

  public final int SIZE = 5000000;
  public CoordsStruct[] dataStruct = new CoordsStruct[SIZE];
}


This is no surprise — Junion can save memory, but it cannot boost the processing time.

Benchmark

Mode

Cnt

Score

Error

Units

TestJavaStruct.testJunion

avgt

200

19.970

± 0.236

ms/op

Conclusion

As I understand it, C#'s struct is a ValueType, and it's "stack-allocated or allocated inline in a structure." So, when we declare an array of Struct, .NET can allocate a region of memory to store the array, and all items of the array are consecutive. Consequently, when we iterate on an array of structs, this action takes advantage of the CPU cache line and performs very fast.

Java is a different story; an array of objects stores only a pointer (or reference, the memory address of the object). Every access might force JVM to read data from memory (or the L3 cache of the CPU). This action isn't "Mechanical Sympathy" and slows down the iteration. You can get more detail about the CPU cache line and how it impacts iteration in my previous article.

Disclaimer: I have not used .NET or C# for professional purposes since 2012, and I know a little bit about Java (a small part of the JVM ecosystem). So, please correct me if I'm wrong; I appreciate any comment or correction.

Data structure Java (programming language) csharp .NET

Opinions expressed by DZone contributors are their own.

Related

  • Immutable Objects Using Record in Java
  • Floyd's Cycle Algorithm for Fraud Detection in Java Systems
  • Merge Multiple PDFs in MuleSoft
  • Scaling Java Microservices to Extreme Performance Using NCache

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook