ページ 11

std::listの優先順位の続き

Posted: 2016年4月12日(火) 15:50
by 夢幻ノ月夜

コード:

void Object_Manager::AddTask(CObject *obj){
	if(List.empty()){
		List.push_front(obj);
		return;
	}
	for(auto itr=List.begin();;){
		if(itr==List.end()){
			List.push_back(obj);
			return;
		}else if((*itr)->operator>(obj)){
			itr=List.insert(itr,obj);
			return;
		}
		itr++;
	}	
}
こうすることで最終的に優先順位が反映されたのですが、何故か物凄く動作が重くなってしまいます
何が原因で負荷がかかっているのでしょうか?

Re: std::listの優先順位の続き

Posted: 2016年4月12日(火) 18:43
by 夢幻ノ月夜
コンパイル設定を変えてoperator >をinlineにしてみたらFPS58まで改善しました

Re: std::listの優先順位の続き

Posted: 2016年4月12日(火) 19:40
by NNN
・ここ以外にもソースを変更していいて、それが原因の可能性はないか
・リストにどれくらいオブジェクトを追加しているか
・「物凄く重く」とか具体的にどの程度か(FPS表示しているなら1桁しか出ないレベルなのか、45程度は出るのか)
・追加するオブジェクトの優先度はどうなっているのか(例えば弾幕の弾が追加していたら、追加するたびにリスト末尾まで毎回判定してたら重くなりそうです)
このあたりの情報が無いと推測回答しか出来ないので的確な回答をするのは難しいと思います。

Re: std::listの優先順位の続き

Posted: 2016年4月12日(火) 20:33
by 夢幻ノ月夜
NNN さんが書きました:・ここ以外にもソースを変更していいて、それが原因の可能性はないか
・リストにどれくらいオブジェクトを追加しているか
・「物凄く重く」とか具体的にどの程度か(FPS表示しているなら1桁しか出ないレベルなのか、45程度は出るのか)
・追加するオブジェクトの優先度はどうなっているのか(例えば弾幕の弾が追加していたら、追加するたびにリスト末尾まで毎回判定してたら重くなりそうです)
このあたりの情報が無いと推測回答しか出来ないので的確な回答をするのは難しいと思います。
他の部分の改変はしていません
リストには1000個入ってないはずです
FPS28くらいになっていました→58まで回復
先頭から判断して優先度的に入れるところで入れてリターンしています

Re: std::listの優先順位の続き

Posted: 2016年4月12日(火) 22:03
by みけCAT

Re: std::listの優先順位の続き

Posted: 2016年4月12日(火) 23:32
by 夢幻ノ月夜
またコンパイラの設定したら3000個でFPS60出たので解決です

Re: std::listの優先順位の続き

Posted: 2016年4月12日(火) 23:56
by へにっくす
解決しちゃったので見てないかもしれませんが。
add_taskは以下のようにできますね。
わざわざempty()とか調べなくともよいです。

コード:

#include <iostream>
#include <list>


class CObject {
public:
    int priority = 0;
    CObject() {
        priority = 0;
    }
    CObject(int prio) {
        priority = prio;
    }
    
    bool operator <(const CObject &obj)const{
        return priority < obj.priority;
    }
};


std::list<CObject*> g_list;


void add_task(CObject *obj) {
    std::list<CObject*>::iterator ptr = g_list.begin();
    for (; ptr != g_list.end(); ptr++) {
        if (*(*ptr) < *obj) {
            g_list.insert(ptr, obj);
            return;
        }
    }
    g_list.push_back(obj);
}


int main() {
    // 適当に追加してみる
    add_task(new CObject(3));
    add_task(new CObject(4));
    add_task(new CObject(7));
    add_task(new CObject(5));
    add_task(new CObject(2));
    add_task(new CObject(1));
    add_task(new CObject(6));

    // リストの中身を表示する
    for (std::list<CObject*>::iterator ptr = g_list.begin(); ptr != g_list.end(); ptr++) {
        std::cout << (*ptr)->priority << std::endl;
    }
}
コンパイル&実行結果

コード:

C:\Users\guest\Documents>cl /EHsc 1.cpp
Microsoft(R) C/C++ Optimizing Compiler Version 18.00.31101 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

1.cpp
Microsoft (R) Incremental Linker Version 12.00.31101.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:1.exe
1.obj

C:\Users\guest\Documents>1
7
6
5
4
3
2
1

C:\Users\guest\Documents>

Re: std::listの優先順位の続き

Posted: 2016年4月13日(水) 07:03
by 夢幻ノ月夜
へにっくす さんが書きました:解決しちゃったので見てないかもしれませんが。
add_taskは以下のようにできますね。
わざわざempty()とか調べなくともよいです。

コード:

#include <iostream>
#include <list>


class CObject {
public:
    int priority = 0;
    CObject() {
        priority = 0;
    }
    CObject(int prio) {
        priority = prio;
    }
    
    bool operator <(const CObject &obj)const{
        return priority < obj.priority;
    }
};


std::list<CObject*> g_list;


void add_task(CObject *obj) {
    std::list<CObject*>::iterator ptr = g_list.begin();
    for (; ptr != g_list.end(); ptr++) {
        if (*(*ptr) < *obj) {
            g_list.insert(ptr, obj);
            return;
        }
    }
    g_list.push_back(obj);
}


int main() {
    // 適当に追加してみる
    add_task(new CObject(3));
    add_task(new CObject(4));
    add_task(new CObject(7));
    add_task(new CObject(5));
    add_task(new CObject(2));
    add_task(new CObject(1));
    add_task(new CObject(6));

    // リストの中身を表示する
    for (std::list<CObject*>::iterator ptr = g_list.begin(); ptr != g_list.end(); ptr++) {
        std::cout << (*ptr)->priority << std::endl;
    }
}
コンパイル&実行結果

コード:

C:\Users\guest\Documents>cl /EHsc 1.cpp
Microsoft(R) C/C++ Optimizing Compiler Version 18.00.31101 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

1.cpp
Microsoft (R) Incremental Linker Version 12.00.31101.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:1.exe
1.obj

C:\Users\guest\Documents>1
7
6
5
4
3
2
1

C:\Users\guest\Documents>
抽象クラスのポインタを入れて3000個回したらどのくらいの負荷になるんだろう

Re: std::listの優先順位の続き

Posted: 2016年4月13日(水) 07:46
by NNN
どうなるんだろう・・・ではなく
みけCAT さんが書きました:
と指摘されているわけですし、デバッグ支援関数を作ってみようのページでデバッグ技術を覚えた方が良いと思います。
ゲーム作りしていた身としてはこれを身に付けるだけで変に試行錯誤していた時間を無くせてゲーム作り捗ると思いますよ。

Re: std::listの優先順位の続き

Posted: 2016年4月14日(木) 00:12
by へにっくす
夢幻ノ月夜 さんが書きました:抽象クラスのポインタを入れて3000個回したらどのくらいの負荷になるんだろう
知るか。ですよ。
自分で取り込むぐらいはできるでしょう?

Re: std::listの優先順位の続き

Posted: 2016年4月14日(木) 01:31
by みけCAT
夢幻ノ月夜 さんが書きました:抽象クラスのポインタを入れて3000個回したらどのくらいの負荷になるんだろう
undefined behaviorが無ければ最悪O(N^2)ですね。 (Nは要素数)
ここに独り言を書き込む前に、まずは実験すればいいでしょう。