Movatterモバイル変換


[0]ホーム

URL:


Yuto Takei, profile picture
Uploaded byYuto Takei
PDF, PPTX1,253 views

Hello Dark-Side C# (Part. 1)

2016/12/1 bitFlyer TechNight C# Meetup での発表。C# における文字列 (string) の高速な取り回しなどについて。https://bitflyer.connpass.com/event/45476/

Embed presentation

Download as PDF, PPTX
Hello Dark-Side C# (Part. 1)Yuto TakeiSoftware EngineerbitFlyer Inc.
免責このトークは、情報提供のみを目的として行われており、正確性・最新性についての保障は一切ありません。内容は、会社の見解ではありません。この情報を元にして生じた不利益について、当社およびスピーカは一切の責任を負いません。bitFlyer 上での取引についての詳細は当社カスタマ サポートへお問い合わせください。
自己紹介Yuto TakeiSoftware Engineerわたしの人生設計¼ : C# と心を通わせる¾ : 美味しいモノを食べる最近、宅建うかりました
文字列について本日のお題は…サンプル コードはhttps://gist.github.com/yutopio/697ac1f75b66fca2b16ceedb9b0c1dd5
文字列のインスタンスC# の文字列は不変です§8.2.1 Predefined typesThe predefined reference types are object and string. The type object is the ultimatebase type of all other types. The type string is used to represent Unicode string values.Values of type string are immutable.[訳]神は object と string という参照型を作りたもうた。 object は万物の根源である。 stringは Unicode 文字列をあらわす。何人も string の値を変えることはできない。– ECMA-334 C# Language Specification, p. 17.“
Insert とか Remove とかあるじゃん… ご存知のとおり、新しい文字列になって返ってきますstring String.Insert(int, string)“Returns a new string in which a specified string is inserted at a specified index position in this instance.”– https://msdn.microsoft.com/library/system.string.insert.aspxstring String.Remove(int, int)“Returns a new string in which a specified number of characters in the current instance beginning at aspecified position have been deleted.”– https://msdn.microsoft.com/library/system.string.remove.aspx
Insert とか Remove とかあるじゃんString result = FastAllocateString(newLength);unsafe{fixed (char* src = &m_firstChar){fixed (char* dst = &result.m_firstChar){wstrcpy(dst, src, startIndex);wstrcpy(dst + startIndex, src + startIndex + count, newLength - startIndex);}}}return result;– Reference Source for .NET 4.6– ndpclrsrcbclsystemstring.cs (Line. 2873 – 2885)← 新しいインスタンスを作ってます
中身を変えたければ、どうするの?System.Text.StringBuilder を使いましょうStringBuilder StringBuilder.Insert(int, string)“Inserts a string into this instance at the specified character position.”– https://msdn.microsoft.com/library/system.text.stringbuilder.insert.aspxStringBuilder StringBuilder.Remove(int, int)“Removes the specified range of characters from this instance.”– https://msdn.microsoft.com/library/system.text.stringbuilder.remove.aspx
中身を変えたければ、どうするの?public StringBuilder Remove(int startIndex, int length) {// ...if (length > 0){StringBuilder chunk;int indexInChunk;Remove(startIndex, length, out chunk, out indexInChunk);}return this;}– Reference Source for .NET 4.6– ndpclrsrcbclsystemtextstringbuilder.cs (Line. 865 – 893, excerpted)← インスタンス自身がそのまま返る
中身を変えたければ、どうするの?public override String ToString() {// ...string ret = string.FastAllocateString(Length);StringBuilder chunk = this;unsafe {fixed (char* destinationPtr = ret); // copy here...}return ret;}– Reference Source for .NET 4.6– ndpclrsrcbclsystemtextstringbuilder.cs (Line. 330 – 368, excerpted)← ToString するたびに← インスタンスが作られる
文字列の intern とは同一文字列は、ひとつのインスタンスにまとめられる(メモリ節約が目的)User Strings-----------------------------70000001 : (10) L"HelloWorld"ldstr "HelloWorld" /* 70000001 */0xDEADBEEF:var hello = "HelloWorld";– or –string.Intern(otherHello); System.String “HelloWorld”
余談: いつ intern されるかCompilationRelaxtions というコンパイラ制御用の属性があり、NoStringInterning という属性を指定することができるusing System.Runtime.CompilerServices;[assembly: CompilationRelaxations(CompilationRelaxations.NoStringInterning)]… 無視されます(intern しなくていいよ、というだけで、結局される)
余談: いつ intern されるかところが Ngen.exe にかけると無条件で intern できなくなる> ngen.exe install ConsoleApp1.exeナンナンダ、この一貫性のなさは!!
ところでなぜ String を char* で fixed できるのかpublic override String ToString() {// ...string ret = string.FastAllocateString(Length);StringBuilder chunk = this;unsafe {fixed (char* destinationPtr = ret); // copy here...}return ret;}– Reference Source for .NET 4.6– ndpclrsrcbclsystemtextstringbuilder.cs (Line. 330 – 368, excerpted)
ところでなぜ String を char* で fixed できるのか仕様です。§27.6 The fixed statementAn expression of type string, provided the type char* is implicitly convertible to the pointertype given in the fixed statement. In this case, the initializer computes the address of thefirst character in the string, and the entire string is guaranteed to remain at a fixed addressfor the duration of the fixed statement.[訳]string 型の式は char* 型が与えられたなら fixed によりポインタに暗黙変換できる。このとき初期化子では文字列の先頭アドレスが計算されて、 fixed スコープ中では文字列全体が固定アドレスに留まることが保障される。– ECMA-334 C# Language Specification, p. 437.“
さて前置きはこのくらいにしておいて…
文字列のインスタンス (復習)C# の文字列は不変です§8.2.1 Predefined typesThe predefined reference types are object and string. The type object is the ultimatebase type of all other types. The type string is used to represent Unicode string values.Values of type string are immutable.[訳]神は object と string という参照型を作りたもうた。 object は万物の根源である。 stringは Unicode 文字列をあらわす。何人も string の値を変えることはできない。– ECMA-334 C# Language Specification, p. 17.“
文字列のインスタンスC# の文字列が、不変だと思っていたでしょう! … 違います (ガタッ)§27.6 The fixed statementModifying objects of managed type through fixed pointers can result in undefined behavior.[Note: For example, because strings are immutable, it is the programmer’s responsibility toensure that the characters referenced by a pointer to a fixed string are not modified. endnote][超意訳]文字列はホントは不変だけど、ポインタで参照された文字列を変えてもイイよ!責任取れるならね! (^ρ^)– ECMA-334 C# Language Specification, p. 439.“
fixed 文字列は、いじれるんじゃね?そのとおり。
文字列インスタンスの生成は特殊public override String ToString() {// ...string ret = string.FastAllocateString(Length);StringBuilder chunk = this;unsafe {fixed (char* destinationPtr = ret); // copy here...}return ret;}– Reference Source for .NET 4.6– ndpclrsrcbclsystemtextstringbuilder.cs (Line. 330 – 368, excerpted)
文字列クラスの双対性 (デュアリティ)public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable{[NonSerialized]private int m_stringLength;[NonSerialized]private char m_firstChar;– Reference Source for .NET 4.6– ndpclrsrcbclsystemstring.cs (Line. 48 – 60, excerpted)対応付けclass StringObject : public Object{DWORD m_StringLength;WCHAR m_Characters[0];– .NET CoreCLR (https://github.com/dotnet/coreclr)– src/vm/object.h (Line. 1087 – 1099, excerpted)
文字列インスタンスの生成は特殊LEAF_ENTRY AllocateStringFastMP_InlineGetThread, _TEXT; We were passed the number of characters in ECX; we need to load the method table for string from the globalmov r9, [g_pStringClass]; Instead of doing elaborate overflow checks, we just limit the number of elements; to (LARGE_OBJECT_SIZE - 256)/sizeof(WCHAR) or less.; This will avoid all overflow problems, as well as making sure; big string objects are correctly allocated in the big object heap.cmp ecx, (ASM_LARGE_OBJECT_SIZE - 256)/2jae OversizedStringmov edx, [r9 + OFFSET__MethodTable__m_BaseSize]; Calculate the final size to allocate.; We need to calculate baseSize + cnt*2, then round that up by adding 7 and anding ~7.lea edx, [edx + ecx*2 + 7]and edx, -8(… 続く)← String 型の情報を読み込み← 文字列長の評価。大きすぎるときは別方法で割り当て← 型のベース サイズを評価(C++ の WCHAR[0] はこのため)← 最終的に必要な領域の計算
文字列インスタンスの生成は特殊PATCHABLE_INLINE_GETTHREAD r11, AllocateStringFastMP_InlineGetThread__PatchTLSOffsetmov r10, [r11 + OFFSET__Thread__m_alloc_context__alloc_limit]mov rax, [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr]add rdx, raxcmp rdx, r10ja AllocFailedmov [r11 + OFFSET__Thread__m_alloc_context__alloc_ptr], rdxmov [rax], r9mov [rax + OFFSETOF__StringObject__m_StringLength], ecxifdef _DEBUGcall DEBUG_TrialAllocSetAppDomain_NoScratchAreaendif ; _DEBUGretOversizedString:AllocFailed:jmp FramedAllocateStringLEAF_END AllocateStringFastMP_InlineGetThread, _TEXTracters[0];– .NET CoreCLR (https://github.com/dotnet/coreclr)– src/vm/amd64/JitHelpers_InlineGetThread.asm– Line. 159 – 204← メモリ割り当てに関する状態の取得← 実際の割り当て← 空き領域の検査← Length プロパティの設定← 高速割り当てがダメだった場合は← SlowAllocateString へ← フォールバック
高速化のための合わせ技みんなパフォーマンス気になりますよね…http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versabyte[] から 16 進数表現 string への変換は、文字列の高速割り当てをして、ポインタで書き込めば、最速のものの約 1.5 倍まで加速できる!
intern した文字列変更したらどうなる?結論: 壊れます
まとめ● 文字列のインスタンスは基本的に不変● 定数は、文字列リテラルのルックアップ テーブルが用いられる● Ngen しない限り、メモリ節約のため、別で作った文字列も intern できる● 文字列はデータ構造がとても特殊● 新しいインスタンスの生成時にはメモリ高速割り当てされる
まとめ (ダーク サイド)● 仕様書に外れる行為をすれば…文字列インスタンスは変更できる (ただし自己責任)● Intern されている変数は、絶対に変更してはいけない● 万が一変更すると、定数などが全部壊れるし、string.Intern が動かなくなるマイクロ最適化楽しい!! ლ(´‫`ڡ‬ლ)
あとがき本日のトークは 2008 年春 (C# 3 の頃) の再放送です。
会場から出た質問まとめ● StringBuilder は意味ないの?○ いえいえ、紹介したテクニックは、あくまで固定長文字列でしか使えないかと。● intern された文字列のライフサイクルは?○ AppDomain でなく System domain だから、仮に変更したら読み込んでいる他の dll の文字列リテラルなどにも影響が出る○ 文字列定数を lock ステートメントに食わせたらプロセス全体に影響出るよ (@ufcpp さん)● fixed した文字列 char* pt に対して ((int*)pt)[-1] を書き換えたら文字列長、いじれるんじゃね?○ いじれますね。ヤヴァい。悪用禁止。実行領域ではないので、不正コード埋められはしないはず ...? (要調査)

Recommended

PDF
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
PDF
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
PDF
Mono is Dead
 
PDF
Inside FastEnum
PDF
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
PDF
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPC
PDF
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
PPTX
Rxに入門しようとしている
PPTX
最速C# 7.x
PPTX
C# 7.2 with .NET Core 2.1
PPTX
C# 8.0 Preview in Visual Studio 2019 (16.0)
PDF
【Unite Tokyo 2019】Understanding C# Struct All Things
PPTX
C# 8.0 非同期ストリーム
PDF
今日からできる!簡単 .NET 高速化 Tips
PDF
Unityで覚えるC#
PDF
きつねさんでもわかるLlvm読書会 第2回
PDF
An Internal of LINQ to Objects
PDF
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
PDF
C++でCプリプロセッサを作ったり速くしたりしたお話
PPTX
.NET Core 2.x 時代の C#
PPTX
ぱっと見でわかるC++11
PDF
Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京
 
PDF
GoCon 2015 Summer GoのASTをいじくって新しいツールを作る
PDF
emc++ chapter32
PDF
Go conference 2017 Lightning talk
PDF
Async design with Unity3D
PPTX
UniRx勉強会 reactive extensions inside(公開用)
PPTX
RuntimeUnitTestToolkit for Unity
PDF
C# でブロックチェーン実装
PPTX
はじめてのASP.NET MVC5

More Related Content

PDF
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
PDF
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
PDF
Mono is Dead
 
PDF
Inside FastEnum
PDF
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
PDF
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPC
PDF
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
PPTX
Rxに入門しようとしている
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
Mono is Dead
 
Inside FastEnum
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPC
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
Rxに入門しようとしている

What's hot

PPTX
最速C# 7.x
PPTX
C# 7.2 with .NET Core 2.1
PPTX
C# 8.0 Preview in Visual Studio 2019 (16.0)
PDF
【Unite Tokyo 2019】Understanding C# Struct All Things
PPTX
C# 8.0 非同期ストリーム
PDF
今日からできる!簡単 .NET 高速化 Tips
PDF
Unityで覚えるC#
PDF
きつねさんでもわかるLlvm読書会 第2回
PDF
An Internal of LINQ to Objects
PDF
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
PDF
C++でCプリプロセッサを作ったり速くしたりしたお話
PPTX
.NET Core 2.x 時代の C#
PPTX
ぱっと見でわかるC++11
PDF
Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京
 
PDF
GoCon 2015 Summer GoのASTをいじくって新しいツールを作る
PDF
emc++ chapter32
PDF
Go conference 2017 Lightning talk
PDF
Async design with Unity3D
PPTX
UniRx勉強会 reactive extensions inside(公開用)
PPTX
RuntimeUnitTestToolkit for Unity
最速C# 7.x
C# 7.2 with .NET Core 2.1
C# 8.0 Preview in Visual Studio 2019 (16.0)
【Unite Tokyo 2019】Understanding C# Struct All Things
C# 8.0 非同期ストリーム
今日からできる!簡単 .NET 高速化 Tips
Unityで覚えるC#
きつねさんでもわかるLlvm読書会 第2回
An Internal of LINQ to Objects
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
C++でCプリプロセッサを作ったり速くしたりしたお話
.NET Core 2.x 時代の C#
ぱっと見でわかるC++11
Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京
 
GoCon 2015 Summer GoのASTをいじくって新しいツールを作る
emc++ chapter32
Go conference 2017 Lightning talk
Async design with Unity3D
UniRx勉強会 reactive extensions inside(公開用)
RuntimeUnitTestToolkit for Unity

Viewers also liked

PDF
C# でブロックチェーン実装
PPTX
はじめてのASP.NET MVC5
PDF
電子情報通信学会グローバル社会とビットコイン(山崎)
PPTX
ASP.NETからASP.NET Coreに移行した話
PDF
Yahoo!ブラウザーにおける市場環境の分析と戦略化
PDF
仮想通貨, Blockchain 関連サービスを支える技術
PDF
5分でわかるブロックチェーンの基本的な仕組み
PDF
グロースハック なぜ我々は無意味な施策を打ってしまうのか
PDF
Fintechベンチャーがもたらす日本市場への示唆
PDF
仮想通貨のブロックチェイン技術によるFinTech
PDF
ブロックチェーンと契約取引
PPTX
Shideshare
PPTX
20140322
PDF
仮想化技術の基本の基本
 
PPTX
仮想通貨エコシステム試論(20140401公開版)
PDF
金融機関向けブロックチェーン・ビジネス
PDF
ブロックチェーンの整理 27 sep2015
PDF
【Jasrac寄附講座】クリエイティブ産業とファイナンス
PDF
ビットコイン ブロックチェーン技術と既存金融サービス事業者の事業戦略
PPTX
[Growth hack]RakutenTravel App Development
C# でブロックチェーン実装
はじめてのASP.NET MVC5
電子情報通信学会グローバル社会とビットコイン(山崎)
ASP.NETからASP.NET Coreに移行した話
Yahoo!ブラウザーにおける市場環境の分析と戦略化
仮想通貨, Blockchain 関連サービスを支える技術
5分でわかるブロックチェーンの基本的な仕組み
グロースハック なぜ我々は無意味な施策を打ってしまうのか
Fintechベンチャーがもたらす日本市場への示唆
仮想通貨のブロックチェイン技術によるFinTech
ブロックチェーンと契約取引
Shideshare
20140322
仮想化技術の基本の基本
 
仮想通貨エコシステム試論(20140401公開版)
金融機関向けブロックチェーン・ビジネス
ブロックチェーンの整理 27 sep2015
【Jasrac寄附講座】クリエイティブ産業とファイナンス
ビットコイン ブロックチェーン技術と既存金融サービス事業者の事業戦略
[Growth hack]RakutenTravel App Development

Similar to Hello Dark-Side C# (Part. 1)

PDF
Boost.Flyweight
PPTX
C# 9.0 / .NET 5.0
PDF
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
PDF
C#勉強会 ~ C#9の新機能 ~
PDF
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
PDF
詳解Dexファイルフォーマット
PDF
Boost Tour 1_58_0 merge
PPTX
C#言語機能の作り方
PDF
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
PDF
プログラミング講座 #6 競プロのテクニック(初級)
PDF
.NET Core 3.0時代のメモリ管理
PPTX
Live Coding で学ぶ C# 7
PDF
New Features in C# 10/11
PDF
C#勉強会
PPTX
Unity C#3からC#6に向けて
PDF
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
PPTX
Deep Dive C# 6.0
PDF
2012.11.17 CLR/H&札幌C++勉強会 発表資料「部分文字列の取得を 効率よく!楽に! - fundoshi.hppの紹介と今後の予定 -」
PDF
iPhone, iPad アプリ開発勉強会#3
PDF
拡張ライブラリ作成による高速化
Boost.Flyweight
C# 9.0 / .NET 5.0
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
C#勉強会 ~ C#9の新機能 ~
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
詳解Dexファイルフォーマット
Boost Tour 1_58_0 merge
C#言語機能の作り方
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
プログラミング講座 #6 競プロのテクニック(初級)
.NET Core 3.0時代のメモリ管理
Live Coding で学ぶ C# 7
New Features in C# 10/11
C#勉強会
Unity C#3からC#6に向けて
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
Deep Dive C# 6.0
2012.11.17 CLR/H&札幌C++勉強会 発表資料「部分文字列の取得を 効率よく!楽に! - fundoshi.hppの紹介と今後の予定 -」
iPhone, iPad アプリ開発勉強会#3
拡張ライブラリ作成による高速化

More from Yuto Takei

PDF
Windows コンテナを AKS に追加する
PDF
これから始めるAzure Kubernetes Service入門
PDF
51% 攻撃の原理とシミュレーション
PDF
[Intermediate 01] イントロダクション / Bitcoin を動作させる
PDF
[Basic 11] 文脈自由文法 / 構文解析 / 言語解析プログラミング
PDF
[Basic 14] 暗号について / RSA 暗号 / 楕円曲線暗号
PDF
ブロックチェーンと仮想通貨 -- 新しいビジネスに挑戦
PDF
[Basic 10] 形式言語 / 字句解析
PDF
開発チームにおける多様性のススメ
PDF
[Basic 13] 型推論 / 最適化とコード出力
PDF
[Intermediate 02] シェルの使い方 / Git, GitHub について
PDF
[Intermediate 04] ブロックチェーンの動作原理
PDF
[Basic 12] 関数型言語 / 型理論
PDF
[Basic 15] ソフトウェアと知的財産権 / ブロックチェーンと計算機科学 / MinChain の紹介
PDF
51% 攻撃の原理とシミュレーション
PDF
ブロックチェーン技術の課題と社会応用
PDF
[Intermediate 03] MinChain - 教育用ブロックチェーンの紹介
PDF
ブロックチェーンの不動産登記への応用に関する検討
PDF
ブロックチェーン神話に迫る - 本当に使える? 使えない?
PDF
ブロックチェーン技術者が夢見る未来
Windows コンテナを AKS に追加する
これから始めるAzure Kubernetes Service入門
51% 攻撃の原理とシミュレーション
[Intermediate 01] イントロダクション / Bitcoin を動作させる
[Basic 11] 文脈自由文法 / 構文解析 / 言語解析プログラミング
[Basic 14] 暗号について / RSA 暗号 / 楕円曲線暗号
ブロックチェーンと仮想通貨 -- 新しいビジネスに挑戦
[Basic 10] 形式言語 / 字句解析
開発チームにおける多様性のススメ
[Basic 13] 型推論 / 最適化とコード出力
[Intermediate 02] シェルの使い方 / Git, GitHub について
[Intermediate 04] ブロックチェーンの動作原理
[Basic 12] 関数型言語 / 型理論
[Basic 15] ソフトウェアと知的財産権 / ブロックチェーンと計算機科学 / MinChain の紹介
51% 攻撃の原理とシミュレーション
ブロックチェーン技術の課題と社会応用
[Intermediate 03] MinChain - 教育用ブロックチェーンの紹介
ブロックチェーンの不動産登記への応用に関する検討
ブロックチェーン神話に迫る - 本当に使える? 使えない?
ブロックチェーン技術者が夢見る未来

Hello Dark-Side C# (Part. 1)


[8]ページ先頭

©2009-2025 Movatter.jp