LoginSignup
11
10

More than 5 years have passed since last update.

JavaとC#の「int」の比較

Last updated at Posted at 2014-12-11

2015/9/16 追記
この記事の最後の速度比較の結論には誤りがあります。
きちんとやれば、C#の結果はもっと速いものになります。

引用元のブログの方が検証されているので、リンクをさせていただきます。
http://crapp.hatenablog.com/entry/2015/01/17/230539

大変失礼をいたしました。

~・~・~・~・~・~・~・~・~・~・~・~・~・~・~・~・~・~

お疲れ様です!きうちです♪

今日は、JavaとC#の比較についてお話します!
ちなみに自分はどちらの言語も大好きで現場経験もあります^^

Javaをご存知でC#をご存知ない方の中には結構
「はっきり言って同じだ」
ということをご存知ない方も多いかと思います。
本題に入る前にここからいきましょうか。

ではまず、HelloWorldを比較してみます。

Java。

HelloWorld.java

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

C#。

HelloWorld.cs
using System;

public class HelloWorld
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
    }
}

表示方法が「System.out.println」と「Console.WriteLine」という風にクラス・メソッドが違いますが、雰囲気は一緒。
表示メソッドがstaticメソッドであるところも一緒。

Javaがjava.lang配下のクラスはをimportしなくてもいいのに対して、C#はSystemをusingしなきゃいけないところとかは違いますが、
Javaの「パッケージ」に対し、C#には「名前空間」というものがあるあたり共通しています。
ま、usingはクラスではなく名前空間を指定するんですが…。

あ、あと.NETには「メソッド名は大文字で始める」って命名ルールがあるからメソッド名が「Main」ってなってますが、字面は一緒。起動引数も一緒。

じゃあ、「1から20までの偶数の合計を計算してみます。」というと。

From1To20.java
public class From1To20 {
    public static void main(String[] args) {
        int sum = 0;
        for (int i = 1; i <= 20; i++) {
            if (i % 2 == 0) {
                sum += i;
            }
        }
        System.out.println(sum);
    }
}
From1To20.cs
using System;

public class From1To20
{
    public static void Main(string[] args)
    {
        int sum = 0;
        for (int i = 1; i <= 20; i++)
        {
            if (i % 2 == 0)
            {
                sum += i;
            }
        }
        Console.WriteLine(sum);
    }
}

本当はこのプログラム、iの初期値を2にしてi+=2すればif文いらなくなるんですが、まあ、if文の比較も見てほしいのであえてこれで^^

変数の宣言も、整数が「int」なのも、for文の書き方もif文の書き方も剰余演算の仕方もまったく一緒です。
あ、波括弧の書き方の標準的なお作法がちょっと違うかな。
ちなみにどちらも「110」と表示されます。

どちらもC言語がご先祖様だから、こうなっているのでしょうね。

せっかくなんで、C言語での「1から20の偶数の合計」も載せておきましょうか。

From1To20.c
#include <stdio.h>

int main(int argc, char *argv[])
{
        int i;
        int sum = 0;
        for (i = 1; i <= 20; i++) {
            if (i % 2 == 0) {
                sum += i;
            }
        }
        printf("%d\n", sum);
}

閑話休題。

実はこの前調べ物をしていて偶然発見したブログで、気になる記述を見つけました。

この中に、プリミティブ型(intとかdoubleとかですね)の話題があって、
「Javaではintはオブジェクト扱いではなく、ヒープメモリにも行かない」というようなお話が書かれています。

たとえばint型変数を文字列化する場合、次のように違いますね。

Java
int a = 256;
String b = Integer.toString(a);
C#
int a = 256;
String b = a.ToString();

C#では、数字が発生した瞬間オブジェクトとみなされますから、

String x = 1.ToString();

みたいな「Java人には気持ち悪い(笑)」書き方もできちゃいますね。
もっとも、JavaでもStringについてはこうだけど。

ところで上記記事、その項目の最後に

※ただし、仮にJavaのプリミティブ型がC#のデータ型よりも高速に機能するのであれば、この仕様は正当化されると思う。ベンチマークもないからなんとも言えんけど。

と気になることが書かれています。

そうか、ベンチマークはないのか。

では、作って検証してみよう!

と思って、作ってみました。

TestOfInt.java
public class TestOfInt {

    /**
     * @param args
     */
    public static void main(String[] args) {
        int ans = 0;

        long start = System.currentTimeMillis();

        for(int j = 0; j < 50000; j++) {
            for(int i = 1; i <= 50000; i++) {
                ans += i;
            }

            for(int i = 1; i <= 50000; i++) {
                ans -= i;
            }
        }

        long end = System.currentTimeMillis();

        System.out.println(end - start + "ms.");
    }

}
Program.cs
using System;
using System.Diagnostics;

namespace TestOfInt
{
    class Program
    {
        static void Main(string[] args)
        {
            int ans = 0;

            Stopwatch sw = new Stopwatch();
            sw.Start();

            for (int j = 0; j < 50000; j++)
            {
                for (int i = 1; i <= 50000; i++)
                {
                    ans += i;
                }

                for (int i = 1; i <= 50000; i++)
                {
                    ans -= i;
                }
            }

            sw.Stop();
            Console.WriteLine("{0}ms.", sw.ElapsedMilliseconds);

            Console.ReadKey();
        }
    }
}

上記は同じものをJavaとC#で書きました。
ある変数に1から50000までの数字を足し、しかる後に1から50000までの数字を引くということを5万回繰り返す、というシンプルかつ「すげー意味のねー」プログラムです。
まるで穴を掘って埋める作業を毎日やっているようです。
でも、動作速度を計るのには十分じゃろと。

あ、所要時間の計り方はまったく同じにはできないので、それぞれのやり方になっています。

結果ですが、

  • Java : 2783ms.
  • C# : 15236ms.

という結果が出ました!

使用したマシンは以下のとおり。

  • CPU : Intel Core-i3 2120 3.30GHz
  • MEM : 4.0GB
  • OS : Windows 7 Professional SP1 (32bit)

どうやら、やはり「オブジェクトにしていない」のは伊達ではないようです。

★ ★ ★

JavaとC#には他にも「同じところ」「似たところ」や「細かく見ると違うところ」などたくさんありますが、そういう比較をしながらコーディングしてみるのもまた乙だなと思っています^^

以上、きうちでした。それではまた!

2014/12/14 追記

C言語版の1から20の偶数の合計について、起動引数の型が間違っていたので修正しました。

2015/9/16 追記

結論に誤りがある旨、冒頭に追記しました。

11
10
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10