我试图提高日常工作的速度,并希望得到一些投入。 情况如下:
在锦标赛中使用拼字游戏,以下条件适用:
目标是为锦标赛进行两次特别的投注:
ID:整数,名称:字符串,分区:整数;
有一个Sidebet表:
PlayerID:Integer,RandomeEachGame:Boolean,RandomAllSame:Boolean;
分数表包含:
PlayerID:整数,GameNumber:整数,分数:整数;
有一个RandomSidebets表:
Player1ID:整数;
Player2ID:整数
GameNumber:整数; //哪个游戏得分为
SameAllGames:Boolean; //如果是,那么配对是针对同一个伙伴的边路,否则它就是不同的伙伴边缘。
我试图创建随机配对,处理似乎过多。我将特定分区中的玩家加载到动态阵列中,然后我从动态阵列中随机拉出,从阵列中移除该项目,这样我就不会在每场比赛中多次使用同一个玩家,并且为合作伙伴做同样的事情,然后将合作伙伴写入表格,以了解合作伙伴。
Var
Division : integer;
I, J : integer;
DSourceUsed : TIntArray;
DSource : TIntArray;
rndnum : integer;
Fld1 : TField;
for Division := 1 to NumberofDivisions do begin
SQLTEXT := 'SELECT sb.PlayerID FROM SIDEBET sb ';
SQLTEXT := SQLTEXT + ' INNER JOIN PLAYERS p ON Sb.PlayerID=p.BPlayerID ';
SQLTEXT := SQLTEXT + Format( ' WHERE (sb.RandomEachGame=) AND (p.Division=%d)', [ Division ] );
Qry.SQL.Text := SQLTEXT;
Qry.Open;
if ( Qry.RecordCount > 0 ) then begin
if RandomMethod = mrmAllSame then begin
SetLength( DSource, Qry.RecordCount );
SetLength( DSourceUsed, Qry.RecordCount );
Qry.First;
Fld1 := Qry.FieldByName( 'PlayerID' );
I := 0;
while not Qry.eof do begin
DSourceUsed[ I ] := Fld1.AsInteger;
DSource[ I ] := Fld1.AsInteger;
inc( I );
Qry.Next;
end;
for I := 0 to Qry.RecordCount - 1 do begin
rndnum := RandomRange( 0, Length( DSourceUsed ) - 1 );
DSource[ I ] := DSourceUsed[ rndnum ];
DeleteX( DSourceUsed, rndnum ); // Routine that removes index from array so we don't repeat partners
end;
for I := 0 to Qry.RecordCount - 1 do begin
if not Odd( I ) then begin
for J := 1 to NumberofGames do begin
QryGame.SQL.Text := Format( 'INSERT INTO RandomSideBets (Player11ID, Player2ID, Game) Values (%d, %d, %d, %d)', [ DSource[ I ], DSource[ I + 1 ], J, True ] );
QryGame.Execute;
end;
end;
end;
end
else begin
for J := 1 to NumberOfGames do begin
SetLength( DSource, Qry.RecordCount );
SetLength( DSourceUsed, Qry.RecordCount );
Qry.First;
Fld1 := Qry.FieldByName( 'PlayerID' );
I := 0;
while not Qry.eof do begin
DSourceUsed[ I ] := Fld1.AsInteger;
DSource[ I ] := Fld1.AsInteger;
inc( I );
Qry.Next;
end;
for I := 0 to Qry.RecordCount - 1 do begin
rndnum := RandomRange( 0, Length( DSourceUsed ) - 1 );
DSource[ I ] := DSourceUsed[ rndnum ];
DeleteX( DSourceUsed, rndnum ); // Delete index from array
end;
for I := 0 to Qry.RecordCount - 1 do begin
if not Odd( I ) then begin
QryGame.SQL.Text := Format( 'INSERT INTO RANDOMSIDEBET (Player1ID, Player2ID, Game, SameAllGames) Values (%d, %d, %d, %b)', [ DSource[ I ], DSource[ I + 1 ], J, FALSE ] );
QryGame.Execute;
end;
end;
end;
end;
end;
Qry.Close;
end;
答案 0 :(得分:1)
您正在进行大量的同步查询,每个查询都要求数据到达服务器并返回(2 *延迟,加上处理时间)。
在本地缓存插入数组,然后当你完成算法时,立即发送它们(你没有提到你的SQL风格,所以你自己),或删除整个事情并写一个存储过程在服务器端执行此操作(与以前相同的附录)。存储过程将避免服务器之间的所有大型数据传输,这是服务器本身的本地传输。
此外,也许是时候使用异步处理了。这是2015年。你的大部分CPU时间浪费在等待I / O(你甚至使用的核心),或什么都不做(可能是你付钱的其他7个核心)。
答案 1 :(得分:0)
您只需要将数据库记录加载到单个数组中,然后您无需对物理记录进行排序或从列表中删除以获得随机化。相反,只需将一个整数数组随机化,作为播放器列表中的索引。
E.g。你加载了50个玩家的列表(我以硬编码50为例,你可以使用适当的变量来实际计算)。
var playerindex: array of integer;
SetLength(playerindex, 50);
for i := 0 to 50 - 1 do
playerindex[i] := Random(50);
现在使用playerindex值索引你的实际玩家列表以获得随机对:
for pair := 0 to 50 div 2 - 1 do // 25 pairs
begin
p1 := players[playerindex[pair * 2]];
p2 := players[playerindex[pair * 2 + 1]];
// record p1 and p2 as each pair of players
end;