読者です 読者をやめる 読者になる 読者になる

続) 気づいたら、C# が C++ の速度を凌駕している!

先日のこの記事ですが、

espresso3389.hatenablog.com

メモリ確保を関数の中でやってるのが悪いんじゃね?疑惑がありまして、そうなのであれば・・・ということで書き直しました。モダンな感じで。

C#

// Compile: csc /o /unsafe speedtest.cs
using System;
using System.Diagnostics;

class SpeedTest
{
  static void test1(byte[] a, int w, int h, int stride)
  {
    for (int y = 0; y < h; y++)
    {
      int offset = y * stride;
      for (int x = 0; x < w; x++)
      {
        a[x + offset] = (byte)(x ^ y);
      }
    }
  }
  
  static unsafe void test2(byte[] a, int w, int h, int stride)
  {
    fixed (byte* p0 = a)
    {
      for (int y = 0; y < h; y++)
      {
        byte* p = p0 + y * stride;
        for (int x = 0; x < w; x++)
        {
          p[x] = (byte)(x ^ y);
        }
      }
    }
  }

  static void time(Action action, int count = 100)
  {
    var tw = new Stopwatch();
    tw.Start();
    for (int i = 0; i < count; i++)
      action();
    tw.Stop();
    Console.WriteLine(tw.ElapsedMilliseconds);
  }

  static void Main(string[] args)
  {
    int w = 4321;
    int h = 6789;
    int stride = (w + 3) & ~3;
    var a = new byte[stride * h];

    time(() => test1(a, w, h, stride));
    time(() => test2(a, w, h, stride));
  }
}

C++

// Compile: cl /MD /Ox /EHsc speedtest.cpp
#include <stdio.h>
#include <windows.h>
#include <functional>
typedef unsigned char byte;

static void test2(byte* a, int w, int h, int stride)
{
  auto p0 = a;
  for (int y = 0; y < h; y++)
  {
    auto p = p0 + y * stride;
    for (int x = 0; x < w; x++)
    {
      p[x] = (byte)(x ^ y);
    }
  }
}

void time(std::function<void()> action, int count = 100)
{
  auto start = GetTickCount();
  for (int i = 0; i < count; i++)
    action();
  printf("%u\n", GetTickCount() - start);
}

int main()
{
  int w = 4321;
  int stride = (w + 3) & ~3;
  int h = 6789;
  auto a = new byte[stride * h];

  time([=]() { test2(a, w, h, stride); });

  delete[] a;
}

計測

さて、C# 版。

2533
1675

次に C++ 版。

1673

おおっと、肉薄する感じに!
正直、何回か動かした感じでは、どっちもどっちです。
どちらが速いとは一概に言えない感じで、誤差の範囲でしょうか。

メモリ確保の影響を除外すると、スピードは同じだと。

感想

正直、やはり、素晴らしい結果ですね。
スピードがほぼ同じ。

まぁ、もはや、 C++C# でコード書く上で何が違うの?って聞かれると、上のコードのように、
結構、1対1対応したコードをそのまま書けるので、意外と何にもハードルがないとも言えるんですが、
ライブラリの充実度や、GC、なんだかんだ言ってもラムダが使いにくい C++ とか考えると、
C# を使いたいです。