編程雜談——std::vector與List 的性能比較


昨天在比較完C++中std::vector的兩個方法的性能差異並留下記錄后——編程雜談——使用emplace_back取代push_back,今日嘗試在C#中測試對應功能的性能。

C#中對應std::vector的數據結構為List 。更多的對應關系可以參照下面:

std::vector - List
std::list - LinkedList
std::map - Dictionary<K, V>
std::set - HashSet
std::multimap - Dictionary<K, List >

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<Item>();
            
            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 <iostream>
#include <vector>
#include <chrono>

class Item
{
public:
	Item(std::string name):name(name){}
private:
	std::string name;
};

int main()
{
	std::vector<Item> 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<Item>();沒有預設容量值,如果改成var l = new List<Item>(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;
};

最后將測試數據量從10W加至1000W后,C++代碼的執行時間約是0.286,而C#的約為0.627。同樣是2倍左右的差距。

值得注意的是,上述的C#代碼是在.NET Core 3.0基礎上測試,如果改成.NET Framwork 4.8,執行時間會降為0.536左右。由此可見,.NET Core應該還留有不少可以優化的地方,希望其在性能方面上能夠進一步改善。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM