Dan seekor tikus dan seekor katak. Kompiler Universal

Dalam serangkaian tentang pemrograman yang andal [1], [2] Swift tetap terlupakan. Sejujurnya, saya hanya tidak menganggapnya cross-platform, tetapi bekerja secara eksklusif untuk macOS / iOS. Itu terjadi secara kebetulan bahwa Swift juga didukung oleh lingkungan pengembangan seperti Elemen RemObjects .

Ternyata dia punya Universal Compiler. Dapat mengkompilasi program dalam C #, Go, Java, Oxygene Object Pascal, Swift untuk: Android, Cocoa (MacOS, iOS, tvOS), JVM, Linux (x64, armv6, aarch64), .NET / .NET Core / Mono, Native Windows (x86 / x64), WebAssembly.

Dan ia melakukan ini di hampir semua kombinasi bahasa → sistem target! Sebagai contoh, Anda dapat menulis sebuah program di Jawa yang akan menggunakan WPF untuk platform .NET target, dan ini semua dalam contoh yang disertakan dengan paket.

Jadi, saya menyajikan catatan kecil tentang Elemen RemObjects, dan pada saat yang sama tentang keandalan dua bahasa yang didukung di dalamnya - Swift dan Oxygene.

Gambar dari radionetplus


Dan selain diskusi tentang masalah interoperabilitas lingkungan runtime yang berbeda - asli, JVM, .NET, GC, ARC, ternyata menjadi sangat sulit dipercaya, dan dalam kedua hal, karena selama diskusi mereka sampai pada kesimpulan bahwa IO normal tidak mungkin.

Secara singkat tentang Elemen RemObjects


Ini adalah lingkungan pengembangan independen dengan debugger, termasuk yang jauh, dan penyelesaian kode untuk Windows atau macOS, atau terintegrasi dengan Visual Studio, dan Xcode diperlukan untuk Cocoa. Untuk Swift, gratis, untuk sisanya biayanya dari $ 199 untuk versi untuk proyek pribadi, hingga $ 799 untuk lisensi komersial untuk semua bahasa. Untuk bekerja dengan DBMS klien - server perlu membayar ekstra secara substansial.

Air adalah nama versi Windows, cukup bertapa, tidak memiliki editor bentuk visual, tetapi bersimpati dengan ketelitian, dan penginstal hanya membutuhkan 700MB, tentu saja, tidak termasuk JRE, .NET, Android NDK, dll.

Untuk memarahinya, atau saya tidak akan memuji banyak, dia melakukan fungsinya, dia tidak pernah jatuh (tetapi ingatan mengalir).

Bonus untuk IDE banyak:

  • ( Water , -)
  • -
  • C#, Swift, Java, Delphi, C, Obj-C Oxygene, C#, Swift, Java, Go
  • Go- . Go
  • -
  • Delphi/VCL


Tentu saja, ada tangkapan kecil bagi mereka yang berpikir bahwa (c) Anda bisa mengambil dan mentransfer program apa pun ke platform lain.

OI di sini adalah bahwa program ini hanya dapat menggunakan kemampuan platform target RTL _and_ untuk semua bahasa dan kombinasinya. Artinya, untuk tujuan .NET, Anda dapat menggunakan WPF, tetapi tidak rt.jar, tetapi untuk Native, hanya WinAPI atau GTK, masing-masing. Tetapi pustaka dasar yang ditulis dalam Oxygene tersedia di mana-mana, seperti halnya lapisan migrasi dengan Delphi - dengan cara mereka tersedia di github .

Sebuah proyek dapat menyertakan sub proyek dalam berbagai bahasa yang didukung oleh RO. Dan dengan impor perpustakaan eksternal, ada juga opsi yang dikembangkan dengan baik.

Manajemen memori akan digunakan dari platform target seperti ARC untuk Kakao. Saya tidak masuk ke detail, untuk Native GC digunakan secara default, meskipun ada pilihan - itu diperiksa, ada dalam proyek saya di github .

Tambahkan satu pengamatan. Jika program ini ditulis di bawah manajemen memori manual (malloc / gratis), itu hanya akan bekerja di bawah ARC. Dan jika program itu di bawah ARC, maka itu akan bekerja tanpa perubahan di bawah GC (kecuali untuk penghancuran segera).

Keandalan


Oksigen


Ini pada dasarnya adalah Object Pascal tua yang sudah dikenal, tetapi pada steroid. Oxygene untuk versi .NET juga dipasarkan sebagai Delphi Prism.

Itu terlihat lebih aman karena:

  • Gc
  • dukungan kontrol nullable
  • ketersediaan kontrak dan invarian
  • kontrol daftar identitas
  • kemampuan untuk mengontrol lekukan pasangan mulai / akhir (tidak jelas cara kerjanya)
  • metode aman kelas yang terkunci / malas
  • menggunakan menggunakan, dalam arti RAII

Minus. GC juga memiliki sisi buruk - non-determinisme sementara, konsumsi memori yang berlebihan. Anda juga dapat menuliskan kerugiannya bahwa skala perusahaan dan komunitasnya kecil, dan karena itu mungkin ada lebih banyak kesalahan implementasi daripada monster techno. Dokumentasi lemah, dan kerangka asli minimal, yang dapat menarik banyak "sepeda" ke dalam proyek jika target Anda bukan .NET atau JRE.

Di sisi teknis, itu menambahkan gula relatif terhadap Delphi:

  • async / menunggu / masa depan, tunggu - sejauh ini hanya untuk .NET
  • LINQ
  • tipe generik / dinamis (berbeda dari Delphi)
  • tupel
  • urutan / hasil
  • interpolasi string

Selingan. C #


Sebelumnya dihilangkan karena cross-platform terbatas, tetapi dengan rilis .NET Core 3, dan munculnya kompiler asli termasuk untuk Linux, itu menjadi sedikit lebih baik. Selain itu, bahasa ini sama-sama didukung dalam RemObjects dengan pemilihan target yang sewenang-wenang.

Sebenarnya, dengan keandalan, C # kurang lebih baik. GC merusak keindahan, tidak nyaman bekerja dengan nullable, yang mengarah ke NPE reguler, kemampuan untuk mendapatkan pengecualian dari fungsi yang tampak tidak bersalah, dan masalah dengan penggunaan LINQ yang tidak berhasil.

Karena GC dan konsumsi sumber daya, itu tidak sangat cocok untuk Tertanam. Selain itu, hanya interpreter tanpa JIT .NET Micro Framework telah ditinggalkan untuk diembed sejak 2015, meskipun dikembangkan sebagai TinyCLR

Sekarang tentang Swift


Pada umumnya, bahasa yang dikompilasi dengan mesin seperti C, salah satu yang terbaru dan dibuat dengan mempertimbangkan sejarah pendahulunya. Dibuat oleh Apple untuk dirinya sendiri, kompiler resmi masih di bawah Ubuntu, ditransfer ke Open Source.

Peluang pada tingkat keandalan memberi perhatian yang layak. Saya bisa mengeluh tentang kemungkinan mengubah kelas konstan dan kemungkinan membingungkan kelas referensi dengan struktur - nilai, namun di sini seperti di C #.

Manajemen memori ada di ARC asli, dan RemObjects untuk platform selain Apple memiliki GC.
Berat untuk Tertanam, tidak ada kemampuan waktu nyata.

Sisanya yang ingin saya lihat hampir semuanya. Tidak ada kontrak (ada ekstensi non-standar di RemObjects), tetapi beberapa jenis persaingan dimungkinkan melalui Property Observers atau @propertyWrapper yang muncul di 5.2 ( belum diimplementasikan dalam RemObjects ) Tuples

harus dicatat, nama parameter fungsi, array.insert(x, at: i)membuka secara eksplisit untuk Opsional, dan umumnya dipikirkan bekerja dengannya.

Nuansa esensial, saya sebut evolusi bahasa. Banyak contoh dari buku teks resmi (5.2) tidak bekerja pada Repl.it (5.0) yang sama, belum lagi RemObjects, yang tidak jelas versi mana yang sesuai .

Implementasi dalam RemObjects berbeda dari referensi satu - Array direferensikan di sini, dan String tidak dapat diubah, antarmuka juga berbeda dari yang dijelaskan dalam tutorial, dan antarmuka perpustakaan tidak hanya memiliki sendiri, tetapi sedikit berbeda antar platform. Yang membawa beberapa variasi ke proses coding membosankan =)

Ringkasan akhir diperbarui tabel keandalan

Sebenarnya, saya mengingatkan Anda bahwa ini hanya dangkal menurut data referensi, dan semua pro yang menulis dalam bahasa ini diundang ke pengeditan keras.

Kualitas kompilasi


Mari kita coba membuat program Swift yang mirip dengan jarak Levenshtein di artikel 0xd34df00d dan bandingkan dengan program-program dari sana.

Cepat
/*    
	  Windows.Native, Elements.Island
*/

class Program {
	 public static func LevDist(_ s1: [UInt8], _ s2: [UInt8]) -> Int32! {
		 let m = s1.count
		 let n = s2.count
		 //  Edge cases.
		 if m == 0 {
			 return n
		 } else {
			 if n == 0 {
				 return m
			 }
		 }

		 var range = Range(0 ... (n + 1))
		 var v0: Swift.Array<Int64> = range.GetSequence()  //17ms

//         var v1 = v0;    // in Swift must copy, but RO make a ref
		 var v1 = Swift.Array<Int64>(v0);

		 var i = 0
		 while i < m {
			 v1[0] = i + 1
			 var j = 0
			 while j < n {
				 let substCost = (s1[i] == s2[j] ? v0[j] : v0[j] + 1)
				 let delCost = v0[j + 1] + 1
				 let insCost = v1[j] + 1
				 v1[j + 1] = substCost < delCost ? substCost : delCost
				 if insCost < v1[j + 1] {
					 v1[j + 1] = insCost
				 }
				 j += 1
			 }

			 let temp = v0; v0 = v1; v1 = temp // copy refs
			 i += 1
		 }
		 return v0[n]
	 }
 }


var b1 = [UInt8](repeating: 61 as! UInt8, count: 20000)
var b2: [UInt8] = b1
var b3 = Swift.Array<UInt8>(repeating: UInt8(63), count: 20000)

print("Start Distance");

var execTimer: StopWatch! = StopWatch()
execTimer.Start()

print(Program.LevDist(b1, b2))
print(Program.LevDist(b1, b3))

execTimer.Stop()

var execTime: Float64 = execTimer.ElapsedMilliseconds / 1000.0 / 10

print("\(execTime) s")
return 0


Selebihnya dengan perubahan minimal, meski tentu saja kekurangan paling parah, saya pangkas pada github . Mereka yang tidak takut dan terlalu malas untuk mengunduh lingkungan dan kompilasi, ada juga binari di sana, jika Anda mau, Anda dapat menjalankan opsi JVM dan NET yang relatif aman, atau di kotak pasir.

Perubahan berkaitan dengan pengeditan untuk RO, penghapusan Encoding.UTF8.GetBytes dari bagian pengukuran, dan ternyata dalam versi Pascal pembentukan garis-garis dalam formulir for i := 1 to 20000 do s1 := s1 + 'a';dapat memakan waktu hingga 4 menit (di luar bagian pengukuran).

Tabel hasil (dinormalisasi oleh Java sebagai universal)
LidahPeronPenyusunWaktuNormaParameter
C #NET4.7NET4.7.306213.075445%-o +
C #Core NET 3.1Elemen 10.011.327385%lepaskan,> dotnet cs.dll
C #Menangkan x64Elemen 10.06.312215%melepaskan
JawaJvmJDK 1.8.0.2422,941100%-g: tidak ada
$ java LevDist
JawaJvmElemen 10.02,85197%release
$java -jar java8.jar
OxygeneNET4.7Elements 10.022,079751%release, range checking off
OxygeneWin x64Elements 10.09,421320%release, range checking off
SwiftJVMElements 10.023,733807%release
$java -jar swiftjvm.jar
SwiftWin x64Elements 10.0131,4004468%release
Go (Beta)Win x64Elements 10.089,2433034%release
Akan menarik untuk menguji WASM, tetapi saya melewatkan poin ini.

Pengukuran dilakukan di mesin virtual dengan Win7, yang memperlambat tugas ini sekitar tiga kali relatif terhadap perangkat keras saya yang sebenarnya, rata-rata diambil dari 5 pengukuran.

Sejauh ini hanya ada satu kesimpulan - kehidupan di Swift juga dimungkinkan di luar ekosistem apel. Namun sejauh ini tidak cepat. Hipotesis bahwa ada masalah dengan Win7, karena Win10 SDK digunakan untuk kompilasi asli, belum dikonfirmasi - pada Server 2016 1607 waktunya hampir sama.

[1] Pemrograman yang andal dalam konteks bahasa - tinjauan noob. Bagian 1
[2] Pemrograman yang andal dalam konteks bahasa. Bagian 2 - Penantang

All Articles