myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Externes » Szenenews » Neues in C#9 - Records, Native Sized Numbers und mehr Syntax-Zucker..
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Neues in C#9 - Records, Native Sized Numbers und mehr Syntax-Zucker..

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.292
Herkunft: BW


Abt ist offline

Neues in C#9 - Records, Native Sized Numbers und mehr Syntax-Zucker..

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Finally hat Microsoft nun auch öffentlich die NEuerungen um C#9 bekannt gegeben.

Die wichtigste Neuerung sind:  Records.

Records sind eine Mischung aus Klassen und Strukturen, die nur das nötigste beinhalten.
Im Entwicklersprachgebraucht wird auch von POCOs geredet - also reine Datenstrukturen.

Der erste Vorschlag war mal

C#-Code:
public record NominalRecord
{
  public int Property { get; }
  public readonly int Field;
}

Nun sieht es aber danach aus, dass wir folgendes erhalten: Data Classes.
[Edit, gfoidl: 23.08.2020] Es schaut so aus als ob doch record bleiben wird.

C#-Code:
public data class NominalRecord
{
  public int Property { get; }
  public readonly int Field;
}

C# bekommt vielen weiteren Syntax-Zucker wie zum Beispiel

C#-Code:
Person person = new Person(123);

kann nun auch

C#-Code:
Person person = new(123);

sein.

Mit Native-Sized Number Types kommt ein neuer Datentyp in die .NET Welt.
Der Datentyp soll vor allem für die effizientere Interop-Kommunikation verwendet werden.

Die gesamte Featureübersicht seht ihr auf  https://github.com/dotnet/roslyn/blob/ma...ure%20Status.md
20.05.2020 17:01 Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team

avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 6.674
Entwicklungsumgebung: VS 2019
Herkunft: Waidring


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

Zitat:
Mit Native-Sized Number Types kommt ein neuer Datentyp in die .NET Welt.
Der Datentyp soll vor allem für die effizientere Interop-Kommunikation verwendet werden.

Nicht nur, sondern v.a. für effizienteren low-level-code, da direkt mit der Wortgröße der CPU gearbeitet werden kann und so der JIT besseren Maschinencode generieren kann. Eine Menge an Hacks und Workarounds die bisher dazu nötig waren werden dadurch eine saubere typsichere Lösung ersetzt.
Motiviert ist dies u.a. durch die starke Verwendung innerhalb von .NET selbst und hier insbesondere bei Methoden die Span<byte> basiert werken und oftmals vektorisiert sind.

mfG Gü
20.05.2020 20:12 Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team

avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 6.674
Entwicklungsumgebung: VS 2019
Herkunft: Waidring


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

siehe dazu auch  Welcome to C# 9.0 von Mads Torgersen.

mfG Gü
20.05.2020 20:20 Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.292
Herkunft: BW

Themenstarter Thema begonnen von Abt

Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von gfoidl:
Nicht nur, sondern v.a. für effizienteren low-level-code, da direkt mit der Wortgröße der CPU gearbeitet werden kann und so der JIT besseren Maschinencode generieren kann.

Also einer der Gründe, der in der Vergangenheit mal genannt wurde, war hier auch Machine Learning.
Hier ist oft keine mega Genauigkeit notwendig, aber dafür eine sehr hohe Geschwindigkeit.

Warum auch immer fehlt dieser doch nachvollziehbare Grund im Blogpost.
20.05.2020 20:40 Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team

avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 6.674
Entwicklungsumgebung: VS 2019
Herkunft: Waidring


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Abt,

Zitat:
keine mega Genauigkeit

nint (Native sized integer) hat mit "Genauigkeit" nichts zu tun.
BTW: das wäre im Kontext von ML auch float / double und da ein float nur halb so groß ist wie eine double, passen in ein SIMD-Register doppelt so viele Werte und somit ist es (ganz grob) doppelt so schnell.

nint ist wirklich low-level auf Assembly-Ebene. Ohne allzu tief in diesem Thread auf die Materie eingehen zu wollen nur kurz ein Beispiel für x64.
Mit int indizierte Zugriffe Arrays schauen (vereinfacht, ohne bound-checks) in Assembly-Code so aus:

Code:
1:
2:
movsxd rax, r8d
mov eax, ptr [rdx+rax]

Störend dabei ist das movsxd, welches das Register r8d, das den Index vom Typ int hält, auf die CPU-Wortbreite "sign extended", also erweitert und das Vorzeichen berücksichtigt. Das ist korrekter Code, aber nicht unbedingt nötig und kann bei sehr vielen Iterationen schon etwas ausmachen.

Möglich wäre jetzt statt dem int einfach long nehmen, da dies 64bit groß ist und somit der CPU-Wortgröße entspricht.
So Problem gelöst. Oder doch nicht? .NET soll "überall" laufen können, also auch auf x86 und da wäre es wieder int.

Genau hier setzt nint an. Es ist unabhängig von der Plattform der Integertyp mit der CPU-Wortbreite. Sinnbildlich kann die "Implementierung" von nint so dargestellt werden:

C#-Code:
#if 64 bit
using nint = System.Int64;  // long
#else
using nint = System.Int32;  // int
#endif

Der gleiche indizierte Zugriff (von oben) mit nint statt int würde folgenden Code erzeugen:

Code:
1:
2:
mov rax, r8
mov eax, ptr [rdx+rax]

Es ist also statt dem movsxd "nur" ein mov und moderne CPUs können dieses spezielle mov sogar eliminieren (dank dem Register-Allocator mit der Register-Renaming Technik). Vllt. generiert der JIT (dank Peephole-Optimization) auch den "idealen" Code:

Code:
1:
mov eax, ptr [rdx+r8]

Es geht dabei nicht nur um den "Austausch" von den CPU-Instruktionen, sondern auch um eine Verringerung der Maschinencode-Größe, welche sich v.a. in Schleifen (positiv) bemerkbar machen kann.

Ohne nint (und Konsorten) musste bisher auf IntPtr-Tricks od. void*-Tricks zurückgegriffen werden. Unleserlicher und fehleranfälliger Code war die Folge. Durch nint kann jetzt der C#-Compiler die nötigen Prüfungen durchführen.

Der netto Effekt / Gewinn schaut relativ gering aus.
Beispielweise profitieren von dieser Änderung / Möglichkeit in .NET so gut wie alle Span-Erweiterungsmethoden (SequenceEquals, IndexOf, ...) und in Folge auch alle String-Vergleichmethoden. Weiter oben im .NET Stack hat dies dann z.B. Vorteile in Kestrel, da es so mehr RPS gibt ;-)

Da du oben Interop zitiert hast, so stimmt es dort auch. In C weiß ja niemand so recht wie groß int ist ;-), daher gibt es dort int32_t und int64_t mit fest definierter Größe. Weiters gibt es dort size_t für den Integertyp mit CPU-Wortgröße.

Bisher gab es bei Interop ein Problem, wenn die native Signatur (aka Deklaration) beispielsweise wie folgt ist:

Code (C):
1:
API_EXPORT void do_something(char* data, size_t index);

Wie sollte nun in C# das DllImport aussehen? int od. long?
V.a. da DllImports statisch typisiert sein müssen, d.h. es kann zur Laufzeit keine andere Signatur verwendet werden.
Das Workaround war keine DllImports zu verwenden und stattdessen per LoadLibrary und Konsorten zur Laufzeiten letztlich einen Delegaten zu erzeugen, welche je nach Environment.Is64BitProcess eine andere Überladung verwendete. Alles umständlich.
Od. man verwendete einfach int od. long und hoffte dass es gut geht. Auch nicht sehr zielführend.
Hatte man die "native Seite" selbst in der Hand -- wie in .NET z.B. die PAL-Layer (platform abstraction) -- so wurde bewusst auf size_t verzichtet und (nur) int32_t verwendet.

Mit nint gehören diese Probleme der Vergangenheit an.

Wie gesagt ist das alles sehr low-level und ein Großteil der C#-Programmierer wird sich darum wohl nie kümmern brauchen ;-)

mfG Gü
20.05.2020 22:30 Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.655
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@gfoidl
Danke für die Erklärung, jetzt wird mir erst der Sinn klar.
Beim durchlesen des Github Issue konnte ich das nicht ganz verstehen wo der Einsatzzweck genau liegen sollte.

Ansonsten warte ich mal ab bis C# 9 zur Verfügung steht und schau mir mal die Einsatzmöglichkeiten im Detail an.
Die Neuerung mit dem data class Ansatz klingt einleuchten und dürfte bestimmt auch Einzug in Entity Framework und andere OR Mapper finden um die Entitäten Klassen von regulären Klasse zu trennen.
Zu mindest kann ich mir diesen Ansatz vorstellen, ob er dann auch kommt steht in den Sternen :o

T-Virus
21.05.2020 08:13 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Coder007
myCSharp.de-Mitglied

Dabei seit: 05.08.2006
Beiträge: 1.211


Coder007 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@gfoidl: ich muss mich ehrlich wundern, dass der Compiler dass nicht sowieso optimieren kann. Gibt es konkrete Gründe, die das verhindern?
21.05.2020 17:20 Beiträge des Benutzers | zu Buddylist hinzufügen
Papst Papst ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.09.2014
Beiträge: 319
Entwicklungsumgebung: VS2017
Herkunft: Kassel


Papst ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@Coder007: der Compiler kennt die Zielplattform nicht, deswegen kann er das nicht alleine.
Anders als bei z.B. C wird nicht Maschinencode erzeugt beim kompilieren von C#
21.05.2020 18:17 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team

avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 6.674
Entwicklungsumgebung: VS 2019
Herkunft: Waidring


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Coder007,

Zitat:
Gibt es konkrete Gründe, die das verhindern?

Wenn ich mich nicht täusche, so die ECMA-Spec auf der .NET beruht. Wenn im Code int steht, so muss letztlich auch int verwendet werden. D.h. weder der C#-Compiler noch der JIT-Compiler dürfen das weg-optimieren.

Nachfolgend meine rein persönliche Einschätzung.

Das könnte zwar beim JITen "aufgeweicht" werden, aber der JIT selbst hat wenig Zeit und Möglichkeiten den Programmfluss genau zu analysieren, denn es könnte sein, dass es tatsächlich ein int bleiben muss damit die Absicht vom Programmierer nicht falsch umgesetzt wird. Daher halte ich es auch für besser, wenn explizit angegeben wird dass es sich um ein nint handelt.
Optimierende C/C++ Compiler haben hier aufgrund der Vorab-Kompilierung mehr Möglichkeiten (und Zeit) und können auch mit int bzw. int32_t optimalen Maschinencode generieren.

Der JIT in .NET an sich ist eine super Sache, es gibt aber auch ein paar "Baustellen" die offen sind und daher suboptimalen Code erzeugen. Durch das Open-Sourcen von .NET wurden aber schon viele Baustellen behoben / verbessert.
Seitens MS geht es dabei aber immer um Priorisierung der offenen Punkte, somit wurde speziell für diesen Fall noch nichts / wenig für automatische Optimierungen umgesetzt. V.a. mit dem Hintergrund dass es mit nint eine explizite Variante gibt.

mfG Gü
21.05.2020 19:50 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 6 Monate.
Der letzte Beitrag ist älter als 6 Monate.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 28.11.2020 08:14