プログラミング雑談——std::vectorとList<br>のパフォーマンス比較
2377 ワード
昨日C++でstd::vectorの2つの方法の性能の違いを比較して記録した後--プログラミング雑談--emplace_を使うback置換push_back,本日はC#で対応機能の性能をテストしてみます.
C#におけるstd::vectorに対応するデータ構造はListである.より多くの対応関係は、以下を参照してください.
std::vector - List std::list - LinkedList std::map - Dictionary std::set - HashSet std::multimap - Dictionary
C#のテストコードは以下の通りです.
プログラム実行結果は約0.077(この値は毎回若干変化する)
一方,C++のテストコードの結果は約0.207であった.これは私たちの一般的な認識とは違います.結局、通常はC++の性能がC#より優れていると思っています.
ここで間違いを犯したのですが、ベンチマークテストを行うには、Releaseモードで行わなければなりません.
Releaseモードに変更すると,C++のコード実行時間は0.003となり,C#も0.061程度に低下した.
しかし、上記C#コードでは、最適化が欠けており、
しかし、C#コードは最適化を継続し、Itemクラスを構造体に変更した後、結果は0.006になった.
C++コードも同様に構造体に変更すると,ほとんど最適化されない.
最後に試験データ量を10 Wから1000 Wに加算した後、C++コードの実行時間は約0.286であり、C#の約0.627であった.同じ2倍くらいの差です.
なお、上記のC#コードは、NET Core 3.0に基づいてテストを行い、変更すれば.NET Framework 4.8では、実行時間が0.536程度に低下します.このことから分かるように.NET Coreには最適化できる点が多く残っているはずで、性能面でさらに改善してほしい.
C#におけるstd::vectorに対応するデータ構造はListである.より多くの対応関係は、以下を参照してください.
std::vector - List std::list - LinkedList std::map - Dictionary std::set - HashSet std::multimap - Dictionary
C#のテストコードは以下の通りです.
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace ConsoleApp
{
class Item
{
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
var sw = new Stopwatch();
sw.Start();
var count = 100000;
var l = new List- ();
for (int i = 0; i < count; i++)
{
l.Add(new Item { Name = "Test" });
}
Console.WriteLine(sw.ElapsedMilliseconds / 1000.0);
}
}
}
プログラム実行結果は約0.077(この値は毎回若干変化する)
一方,C++のテストコードの結果は約0.207であった.これは私たちの一般的な認識とは違います.結局、通常はC++の性能がC#より優れていると思っています.
#include
#include
#include
class Item
{
public:
Item(std::string name):name(name){}
private:
std::string name;
};
int main()
{
std::vector- v;
int count = 100000;
v.reserve(count);
clock_t begin_time = clock();
for (auto i = 0; i < count; i++)
{
v.emplace_back("Test");
}
std::cout << float(clock() - begin_time) / CLOCKS_PER_SEC << std::endl;
}
ここで間違いを犯したのですが、ベンチマークテストを行うには、Releaseモードで行わなければなりません.
Releaseモードに変更すると,C++のコード実行時間は0.003となり,C#も0.061程度に低下した.
しかし、上記C#コードでは、最適化が欠けており、
var l = new List- ();
には予め設定された容量値がなく、var l = new List- (count);
に変更すると、実行時間はさらに0.050程度に低下する.しかし、C#コードは最適化を継続し、Itemクラスを構造体に変更した後、結果は0.006になった.
struct Item
{
public string Name { get; set; }
}
C++コードも同様に構造体に変更すると,ほとんど最適化されない.
struct Item
{
public:
Item(std::string name):name(name){}
private:
std::string name;
};
最後に試験データ量を10 Wから1000 Wに加算した後、C++コードの実行時間は約0.286であり、C#の約0.627であった.同じ2倍くらいの差です.
なお、上記のC#コードは、NET Core 3.0に基づいてテストを行い、変更すれば.NET Framework 4.8では、実行時間が0.536程度に低下します.このことから分かるように.NET Coreには最適化できる点が多く残っているはずで、性能面でさらに改善してほしい.