Windows上でtoupperの実行速度が大幅に遅いクロスプラットフォーム(WindowsおよびLinux)アプリケーションで、エッジケースを診断しています。私はこれがtolowerでも同じであると仮定しています。ロケール設定時にWindows Cランタイムが遅くなる
私はこれをロケール情報が設定されていない単純なCプログラムでテストしました。ヘッダーファイルも含まれていましたが、パフォーマンスの違いはほとんどありませんでした。 Testはtoupper()関数に文字列を渡すために各文字を呼び出す百万回の繰り返しループでした。
ヘッダーファイルをインクルードした後、その行をインクルードした後は、はるかに遅くなり、多くのMS Cランタイムライブラリのロケール固有の関数が呼び出されます。これは問題ありませんが、パフォーマンスヒットは本当に悪いです。 Linuxでは、パフォーマンスに何の影響も与えません。
setlocale(LC_ALL, ""); // system default locale
私は次のように設定している場合、それは、Linuxのように高速で動作しますが、すべてのロケール関数をスキップするように見えるん。
setlocale(LC_ALL, NULL); // should be interpreted as the same as below?
OR
setlocale(LC_ALL, "C");
注:セントOS
は、Windows、Linux上ノー速度差に遅いオランダ設定の設定と同じ結果を、試してみましたを実行しているLinux用のWindows 10 G ++用 のVisual Studio 2015。
私は間違ったことをやっているのですか、Windowsでのロケール設定にバグがありますか?それとも、Linuxが何をしていないのですか? 私はLinuxに慣れていないので、内部的に何をしているのか正確にはわからないので、私はLinuxアプリケーションでデバッグを行っていません。 これを整理するために次に試すべきは何ですか?テストのために、以下の
コード(Linuxの):Windows用の
// C++ is only used for timing. The original program is in C.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <chrono>
#include <locale.h>
using namespace std::chrono;
void strToUpper(char *strVal);
int main()
{
typedef high_resolution_clock Clock;
high_resolution_clock::time_point t1 = Clock::now();
// set locale
//setlocale(LC_ALL,"nl_NL");
setlocale(LC_ALL,"en_US");
// testing string
char str[] = "the quick brown fox jumps over the lazy dog";
for (int i = 0; i < 1000000; i++)
{
strToUpper(str);
}
high_resolution_clock::time_point t2 = Clock::now();
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
printf("chrono time %2.6f:\n",time_span.count());
}
void strToUpper(char *strVal)
{
unsigned char *t;
t = (unsigned char *)strVal;
while (*t)
{
*t = toupper(*t);
*t++;
}
}
にローカル情報を変更します。
// set locale
//setlocale(LC_ALL,"nld_nld");
setlocale(LC_ALL, "english_us");
あなたが完了した時刻における分離器からのロケールの変更、完全な停止を見ることができますコンマ対。
EDIT - プロファイリングデータ 上記のように、_toupper_lからの子システムコールに費やされた時間はほとんどの時間です。 ロケール情報が設定されていないと、トゥーパーコールは子の_toupper_lを呼び出さず、非常に速くなります。
C++、タグ付けする。 – 3442
完全に最適化された「リリース」ビルドに対してこれをテストしていますか?また、GCCがループから完全に最適化している可能性もあります。なぜなら、あなたはループからの出力値を派生せず、文字列は 'volatile'ではないからです。 – paddy
@paddyリリースビルドでは、私のオリジナルコードは最後に文字列を出力し、変数を設定しました。私はそれを単純化しました。反復回数を増やすと時間が長くなりますので、ループを最適化することはできません。これは、依然として出力を使用する生産アプリケーションのパフォーマンスの問題を説明していません。 –