C# や C++ でこの種の計算を実行する利点があるとしたら、私は非常に驚かれることでしょう。SQL サーバーから C# または C++ プログラムにデータを転送するのにかかる時間は、速度の違いをはるかに上回ります。SQL サーバーは、C++ または C# コードが使用するのと同じ C または C++ ライブラリ (または少なくとも 1 つに非常に類似したもの) を引き続き使用することに注意してください。そのため、実際のexp
計算log
自体の速度は非常に似ています。オーバーヘッドは、SQL 要素の解析から発生します。そして、私はまったく大きな違いがあるとは思わない。
これが問題だと本当に思うなら (私はしませんが、私はあなたがしている作業に責任を負いません...)、現実的な値を持ついくつかのテーブルでテストケースを構築することをお勧めします.と現実的なサイズ (そしておそらく少し大きい) を比較し、値を計算する速度と値を直接フェッチする速度を比較します (純粋な SQL コードで - 使用できる SQL コマンドライン ツール、またはいくつかの Web があると思います)。 -インターフェイスまたは計算を実行できるようにするもの)。おそらくsum
、値だけを返すこともできます。
編集: 私は PHP をいくつか書きました (私のマシンには既に PHP + MySQL 環境がほとんどインストールされているため)。[いいえ、それらは私のユーザー名とパスワードの組み合わせではありません。そのような公開サーバーに投稿するつもりはありません!]
<?php
$dbconnect = mysql_connect("localhost", "username", "password");
if (!$dbconnect)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("test", $dbconnect)
or die ("Couldn't connect to database: " . mysql_error() );
echo "Argv[1]=" . $argv[1] . "\n";
if ($argv[1] == "Create")
{
$rm = getrandmax();
for($i = 0; $i < 100000; $i++)
{
$a = rand() / $rm;
$b = rand() / $rm;
$c = rand() / $rm;
$d = rand() / $rm;
$e = rand() / $rm;
$f = rand() / $rm;
$sql = "INSERT INTO test1 (id, a, b, c, d, e, f) VALUES ("
. $i .
", " . $a . ", " . $b . ", " . $c . ", " . $d . ", " . $e
. ", " . $f . ");";
if (mysql_query($sql, $dbconnect) === false)
{
die("Could not add element " . mysql_error());
}
}
}
if ($argv[1] == "ExpSumLog")
{
$sql = "SELECT exp(sum(log(a))) AS a1,
exp(sum(log(b))) AS b1,
exp(sum(log(c))) AS c1,
exp(sum(log(d))) AS d1,
exp(sum(log(e))) AS e1
FROM test1
GROUP BY e,f,id";
$result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
$count = 0;
$sum = 0;
while($row = mysql_fetch_assoc($result))
{
$count++;
$sum += $row['a1'];
}
echo "Sum=" . $sum . ", count=" . $count . "\n";
}
if ($argv[1] == "Sum")
{
$sum = 0;
$sql = "SELECT sum(a) AS a1,
sum(b) AS b1,
sum(c) AS c1,
sum(d) AS d1,
sum(e) AS e1
FROM test1
GROUP BY e,f,id";
$result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
$count = 0;
while($row = mysql_fetch_assoc($result))
{
$count++;
$sum += $row['a1'];
}
echo "Sum=" . $sum . ", count=" . $count . "\n";
}
if ($argv[1] == "List")
{
$sum = 0;
$sql = "SELECT * FROM test1;";
$result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
$count = 0;
while($row = mysql_fetch_assoc($result))
{
$count++;
$sum += $row['a'];
}
echo "Sum=" . $sum . ", count=" . $count . "\n";
}
if ($argv[1] == "SumA")
{
$sum = 0;
$sql = "SELECT sum(a) FROM test1;";
$result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
$count = 0;
while($row = mysql_fetch_assoc($result))
{
$count++;
$sum += $row['sum(a)'];
}
echo "Sum=" . $sum . ", count=" . $count . "\n";
}
if ($argv[1] == "ExpSumLogA")
{
$sum = 0;
$sql = "SELECT sum(exp(log(a))) AS a1 FROM test1;";
$result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
$count = 0;
while($row = mysql_fetch_assoc($result))
{
$count++;
$sum += $row['a1'];
}
echo "Sum=" . $sum . ", count=" . $count . "\n";
}
?>
作成には約 55 分かかります... 幸いなことに、他の手順ははるかに高速です。
Argv[1]=ExpSumLog
Sum=50017.011061374, count=100000
real 0m1.102s
user 0m0.289s
sys 0m0.066s
Argv[1]=Sum
Sum=50017.011061374, count=100000
real 0m1.004s
user 0m0.278s
sys 0m0.055s
Argv[1]=List
Sum=50017.011061374, count=100000
real 0m0.993s
user 0m0.322s
sys 0m0.060s
Argv[1]=SumA
Sum=50017.011061374, count=1
real 0m0.068s
user 0m0.019s
sys 0m0.012s
Argv[1]=ExpSumLogA
Sum=50017.011061374, count=1
real 0m0.095s
user 0m0.024s
sys 0m0.017s
ご覧のとおり、実際の計算を実行するのにかかる時間は、すべてのデータをコピーするのにかかる時間よりもはるかに短いです。また、データを sum(exp(log(a))) と sum(a) として計算する場合の違いはわずかに異なります (ただし一貫して異なります - ExpSumLogA と SumA では、すべての実行が約 20 ~ 30 ミリ秒遅くなります)。
主要なポイントがデータ転送であることを証明するために、次の 4 つのバリアントを追加しました。
if ($argv[1] == "SortedA")
{
$sum = 0;
$sql = "SELECT a AS a1 FROM test1 ORDER BY a;";
$result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
$count = 0;
while($row = mysql_fetch_assoc($result))
{
$count++;
$sum += $row['a1'];
}
echo "Sum=" . $sum . ", count=" . $count . "\n";
}
if ($argv[1] == "SortedExpLogA")
{
$sum = 0;
$sql = "SELECT exp(log(a)) AS a1 FROM test1 ORDER BY a;";
$result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
$count = 0;
while($row = mysql_fetch_assoc($result))
{
$count++;
$sum += $row['a1'];
}
echo "Sum=" . $sum . ", count=" . $count . "\n";
}
if ($argv[1] == "UnsortedA")
{
$sum = 0;
$sql = "SELECT a AS a1 FROM test1;";
$result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
$count = 0;
while($row = mysql_fetch_assoc($result))
{
$count++;
$sum += $row['a1'];
}
echo "Sum=" . $sum . ", count=" . $count . "\n";
}
if ($argv[1] == "UnsortedExpLogA")
{
$sum = 0;
$sql = "SELECT exp(log(a)) AS a1 FROM test1;";
$result = mysql_query($sql, $dbconnect) or die("Failed " . mysql_error());
$count = 0;
while($row = mysql_fetch_assoc($result))
{
$count++;
$sum += $row['a1'];
}
echo "Sum=" . $sum . ", count=" . $count . "\n";
}
明らかに、これらの亜種はすべてのデータをエクスポートするよりも速く実行されますが、「値を 1 つだけ返す」ものよりは遅くなります。
Argv[1]=SortedA
Sum=50017.011061375, count=100000
real 0m0.375s
user 0m0.194s
sys 0m0.027s
Argv[1]=SortedExpLogA
Sum=50017.011061375, count=100000
real 0m0.394s
user 0m0.202s
sys 0m0.023s
Argv[1]=UnsortedA
Sum=50017.011061374, count=100000
real 0m0.353s
user 0m0.206s
sys 0m0.018s
Argv[1]=UnsortedExpLogA
Sum=50017.011061374, count=100000
real 0m0.383s
user 0m0.223s
sys 0m0.025s
ご覧のとおり、ソート済みの方が未ソートよりも時間がかかります (100K のアイテムをソートする必要がある場合は、時間が追加されると予想されます)。 A」の変種。このようにかなり一貫しています。