- 投稿日:2020-12-27T23:56:08+09:00
.NET 5.0のコンソールアプリケーション簡易性能検証
はじめに
Delphi 5で作成されていたインターフェイス用のコンソールアプリケーションがあり、C# に作り変えました。
ただ社内検証では問題が発生しなかったが、ユーザー環境では1回ごとの起動処理が3秒ほどかかるとして導入が見送りになりました。その後にいろいろ調査して、固定IPアドレスとプロクシの自動検出が原因でした。
【.NET】HttpClientの初回が遅いのはプロクシの自動検出が原因起動処理が3秒ほどかかる問題は解決したものの、導入は1年以上経っても何故か進みません。Delphi 5版は長年使用していて安定しているってのもありますが、Delphi 5版 と C#版 のWindows 7での性能検証で差が出ているのが一つの要因になっているのかも知れません。ただ作業者の運用を考えたら問題ないレベルではあると思っているのですが説得できる材料が乏しいのか、他の言語で作成した場合とDelphiの最新版に変更した場合の開発工数の依頼がきてました。
仕様
C++ のアプリケーション側から、CreateProcessでexe形式のインターフェイスを呼ぶようになっています。
インターフェイス側では呼び出し側から渡されたパラメーターを解析して、Webサーバー(IIS 10.0 + ASP.NET + Classic ASP)で処理(DBアクセス等)をして、結果をテキストファイル(Result.txt)に返すようになっています。.NET 5.0に移植
来年の2月頃に、Raspberry Piで動作させる依頼がくるかも知れないということで、.NET Framework 4.x から .NET 5.0 に移植してみました。Raspberry Piの実機がないので動作するかはまだ確認していません。
「'shift_jis' is not a supported encoding name.」のエラーになった以外は、問題なく移植できました。
.NET CoreでShift-JISを取り扱う方法性能検証
環境
- ① Windows 10 IoT 64bit Intel Core(TM) i3-8145U CPU 2.10GHz 2.30GHz メモリ 4.0GB
- ② Windows 10 Pro 64bit Intel Core(TM) i7-8565U CPU 1.80GHz 2.00GHz メモリ 8.0GB
- ③ Windows Server 2016 Intel Xeon CPU 3 E3-1220 v6 3.00GHz 3.00GHz メモリ 16.0GB
①は工場などの制御端末や組み込み端末用で「機能更新プログラム」が提供されず10年間機能固定でご利用するもの。
②は会社で支給された自分が現在使用しているもの
③はサーバーです。インターフェイスはクライアントPC側で動かすものなので参考用です。インターフェイスアプリケーションは、Windows 7 PCでも動作するように 32bitアプリケーション(x86)になっています。
検証方法
C++でCreateProcessでexe形式のインターフェイスアプリケーションを呼び出し、処理時間のログを出力するだけのドライバアプリケーションを作成して4回実行します。ただ初回のみ時間がかかる(コールドスタートアップ)ため除外、実質3回の平均を取ります。
- Delphi
- .NET Framework 4.x
- .NET 5.0
- .NET 5.0 自己完結型
※自己完結型は、ランタイム込みで配布先に.NET 5.0がインストールされていなくても動く形式です。
検証実施
平均は初回のみ除外
① Windows 10 IoT 64bit Intel Core(TM) i3-8145U CPU 2.10GHz 2.30GHz メモリ 4.0GB
プラットフォーム 初回 2回目 3回目 4回目 平均ms Delphi 2188 636 652 601 629.7 .NET 4.x 8618 785 629 690 701.3 .NET 5.0 4497 874 817 841 844 .NET 5.0 Self 3301 1253 1218 1237 1236 ② Windows 10 Pro 64bit Intel Core(TM) i7-8565U CPU 1.80GHz 2.00GHz メモリ 8.0GB
プラットフォーム 初回 2回目 3回目 4回目 平均ms Delphi 495 299 292 270 287 .NET 4.x 2704 295 358 355 336 .NET 5.0 1496 559 637 578 591.3 .NET 5.0 Self 2560 1787 1763 1817 1789 ③ Windows Server 2016 Intel Xeon CPU 3 E3-1220 v6 3.00GHz 3.00GHz メモリ 16.0GB
プラットフォーム 初回 2回目 3回目 4回目 平均ms Delphi 349 116 112 119 115.7 .NET 4.x 1047 128 116 114 119.3 .NET 5.0 429 240 212 234 228.7 .NET 5.0 Self 917 460 432 418 436.7 結果まとめ
Delphi と .NET Framework 4.x については同等性能です。※Delphi版はネイティブコードです。
.NET 5.0 に関しては、パフォーマンスが向上したと聞いていたが、この検証においては100ms〜200ms遅いです。
.NET 5.0 自己完結型は、exeサイズが大きいだけあって今回のように随時呼ばれるのには向いてないです。Windows ServerくらいPC性能がよければ使用しても問題ないでしょう。最後に
.NET 5.0 に関しては、パフォーマンスが向上したと聞いていたので少し残念な結果です。でも、Raspberry Piはコンパイルするだけで動作するようになるのだから、開発効率はいいです。とはいえ、Raspberry Piで試してないので遅くて使い物にならなかったら、C++あたりで作り直すことになるのかも。
ユーザー側はWindows 7のPCがまだ大半なので、本来はWindows 7の性能検証結果を入れたかったのですが、環境準備が整わなかったので今後追加しておきます。また、Raspberry Piも検証できる環境ができたときには反映しておきます。
- 投稿日:2020-12-27T16:33:26+09:00
TwitterのDM投稿バッチ Ver.C#
Program.csusing System; using CoreTweet; using Newtonsoft.Json; namespace ConsoleApp1 { #region JsonClass public class Target { public long recipient_id { get; set; } } public class Media { public long id { get; set; } } public class Attachment { public string type { get; set; } public Media media { get; set; } } public class MessageData { public string text { get; set; } public Attachment attachment { get; set; } } public class MessageCreate { public Target target { get; set; } public MessageData message_data { get; set; } } public class Event { public string type { get; set; } public MessageCreate message_create { get; set; } } public class Root { public Event @event { get; set; } } #endregion class Program { static void Main(string[] args) { //今日の日付文字列を取得 string yyyyMMdd = DateTime.Now.ToString("yyyyMMdd"); //ユーザID(DMを送信するuser_id) Int64 useID = <ユーザID>; //メッセージ string dmMessage = @"今日の一枚?"; //画像ファイルパス string imgFilePath = @"C:\Users\<画像フォルダパス>\img_" + yyyyMMdd + ".jpg"; //API key string apiKey = "<APIキー>"; //API secret key string apiSecretKey = "<APIシークレットキー>"; //Access token string accessToken = "<アクセストークン>"; //Access token secret string accessTokenSecret = "<アクセストークンシークレット>"; //認証情報 var tokens = CoreTweet.Tokens.Create(apiKey, apiSecretKey, accessToken, accessTokenSecret); //画像ファイルを取得 System.IO.FileInfo imgFileInfo = new System.IO.FileInfo(imgFilePath); //画像をアップロードしてmedia_idを取得 var mediaId = tokens.Media.Upload(imgFileInfo); //JSONオブジェクトを生成 Media jsonMedia = new Media(); jsonMedia.id = Int64.Parse(mediaId.ToString()); Attachment jsonAttachment = new Attachment(); jsonAttachment.type = "media"; jsonAttachment.media = jsonMedia; Target jsonTarget = new Target(); jsonTarget.recipient_id = useID; MessageData jsonMessageData = new MessageData(); jsonMessageData.text = dmMessage; jsonMessageData.attachment = jsonAttachment; MessageCreate jsonMessageCreate = new MessageCreate(); jsonMessageCreate.target = jsonTarget; jsonMessageCreate.message_data = jsonMessageData; Event jsonEvent = new Event(); jsonEvent.type = "message_create"; jsonEvent.message_create = jsonMessageCreate; Root jsonRoot = new Root(); jsonRoot.@event = jsonEvent; //JSONを文字列変換 var jsonStr = JsonConvert.SerializeObject(jsonRoot); //バイト配列に変換 byte[] jsonData = System.Text.Encoding.UTF8.GetBytes(jsonStr); //DM送信 tokens.PostContent("https://api.twitter.com/1.1/direct_messages/events/new.json", "application/json", jsonData); } } }Follow @miki1220jp
↑よろしくお願いしますぜひぜひ
▼ 参考リンク!ありがとうございます
https://effect.hatenablog.com/entry/2018/09/16/023653 - TwitterAPIを利用するまで
https://blog.fkoji.com/2018/07240244.html - JSONリクエストサンプル
https://greenspace.info/mt/2011/05/19/twitter_api_dm.html - アクセス権エラー時に
https://json2csharp.com/json-to-csharp - JSON文字列をC#のクラスにしてくれる
https://idtwi.com/ - TwitterのユーザID取得
http://coretweet.github.io/docs/classCoreTweet_1_1Core_1_1TokensBase.html - CoreTweetのリファレンス
https://tools.m-bsys.com/development_tooles/json-beautifier.php - JSONを整形
- 投稿日:2020-12-27T16:33:26+09:00
TwitterのDMを送信するバッチ Ver.C#
Program.csusing System; using CoreTweet; using Newtonsoft.Json; namespace ConsoleApp1 { #region JsonClass public class Target { public long recipient_id { get; set; } } public class Media { public long id { get; set; } } public class Attachment { public string type { get; set; } public Media media { get; set; } } public class MessageData { public string text { get; set; } public Attachment attachment { get; set; } } public class MessageCreate { public Target target { get; set; } public MessageData message_data { get; set; } } public class Event { public string type { get; set; } public MessageCreate message_create { get; set; } } public class Root { public Event @event { get; set; } } #endregion class Program { static void Main(string[] args) { //今日の日付文字列を取得 string yyyyMMdd = DateTime.Now.ToString("yyyyMMdd"); //ユーザID(DMを送信するuser_id) Int64 useID = <ユーザID>; //メッセージ string dmMessage = @"今日の一枚?"; //画像ファイルパス string imgFilePath = @"C:\Users\<画像フォルダパス>\img_" + yyyyMMdd + ".jpg"; //API key string apiKey = "<APIキー>"; //API secret key string apiSecretKey = "<APIシークレットキー>"; //Access token string accessToken = "<アクセストークン>"; //Access token secret string accessTokenSecret = "<アクセストークンシークレット>"; //認証情報 var tokens = CoreTweet.Tokens.Create(apiKey, apiSecretKey, accessToken, accessTokenSecret); //画像ファイルを取得 System.IO.FileInfo imgFileInfo = new System.IO.FileInfo(imgFilePath); //画像をアップロードしてmedia_idを取得 var mediaId = tokens.Media.Upload(imgFileInfo); //JSONオブジェクトを生成 Media jsonMedia = new Media(); jsonMedia.id = Int64.Parse(mediaId.ToString()); Attachment jsonAttachment = new Attachment(); jsonAttachment.type = "media"; jsonAttachment.media = jsonMedia; Target jsonTarget = new Target(); jsonTarget.recipient_id = useID; MessageData jsonMessageData = new MessageData(); jsonMessageData.text = dmMessage; jsonMessageData.attachment = jsonAttachment; MessageCreate jsonMessageCreate = new MessageCreate(); jsonMessageCreate.target = jsonTarget; jsonMessageCreate.message_data = jsonMessageData; Event jsonEvent = new Event(); jsonEvent.type = "message_create"; jsonEvent.message_create = jsonMessageCreate; Root jsonRoot = new Root(); jsonRoot.@event = jsonEvent; //JSONを文字列変換 var jsonStr = JsonConvert.SerializeObject(jsonRoot); //バイト配列に変換 byte[] jsonData = System.Text.Encoding.UTF8.GetBytes(jsonStr); //DM送信 tokens.PostContent("https://api.twitter.com/1.1/direct_messages/events/new.json", "application/json", jsonData); } } }Follow @miki1220jp
↑よろしくお願いしますぜひぜひ
▼ 参考リンク!ありがとうございます
https://effect.hatenablog.com/entry/2018/09/16/023653 - TwitterAPIを利用するまで
https://blog.fkoji.com/2018/07240244.html - JSONリクエストサンプル
https://greenspace.info/mt/2011/05/19/twitter_api_dm.html - アクセス権エラー時に
https://json2csharp.com/json-to-csharp - JSON文字列をC#のクラスにしてくれる
https://idtwi.com/ - TwitterのユーザID取得
http://coretweet.github.io/docs/classCoreTweet_1_1Core_1_1TokensBase.html - CoreTweetのリファレンス
https://tools.m-bsys.com/development_tooles/json-beautifier.php - JSONを整形
- 投稿日:2020-12-27T10:11:25+09:00
変数って何???
ここではC#における変数を説明したいと思います。
変数とは、物を入れるための箱だと思ってください。ただ、現実にある箱は入れれる物の大きさは決まってませんが、プログラミングの世界では決まっています。使い方は、
変数の型 自分で決めた変数名 = 入れたいもの;です。
たとえば、1という値を入れたい場合は
int number = 1;
です。もし、1が値ではなく文字として1と入れたい場合は
char number = '1';
もし、111と値として使いたい場合は
int number = 111;
とすればいいのですが、もし値ではなく、文字としてどうすれば良いでしょうか??
実際に、
char kazu='111';
としてみると、VisualStudioの画面に赤い破線が出ています(小さくて分かりにくいかもしれません)
そこへカーソルを持っていくと、説明が出ます。
説明はCS1012:文字リテラルに文字数が多すぎます。と出ていますね。
これは、文字しか入れれない箱に文字列を入れてしまったので、文字数が多すぎるというエラーでした。
では、文字列はどうするの??型名 文字列 C#で検索してみると
string というものが出てきます。
では使ってみましょう。
今度は、なんのエラーも出ていません。変数の型には他にもたくさんあるので、変数の型名 C#で検索してみてください。
変数の名前は付けるのに迷うこともあると思います。
そこで、下記を参考にしてみてください。
プログラマやシステムエンジニアの為のネーミングサイトで無料で使うことができます。
https://codic.jp/