Rumah hujung hadapan web tutorial js Bersaing dengan JSON.stringify - dengan membina yang tersuai

Bersaing dengan JSON.stringify - dengan membina yang tersuai

Aug 14, 2024 pm 02:35 PM

Competing with JSON.stringify - by building a custom one

Ini muncul semasa perbincangan dengan rakan saya tentang Rekursi. Mengapa tidak membina
kaedah Javascript JSON.stringify sebagai latihan pengaturcaraan rekursif? Nampak sangat
idea.

Saya dengan cepat merangka versi pertama. Dan ia beraksi dengan dahsyat!
masa yang diperlukan adalah kira-kira 4 kali ganda daripada standard JSON.stringify.

Draf pertama

function json_stringify(obj) {
  if (typeof obj == "number" || typeof obj == "boolean") {
    return String(obj);
  }

  if (typeof obj == "string") {
    return `"${obj}"`;
  }

  if (Array.isArray(obj)) {
    return "[" + obj.map(json_stringify).join(",") + "]";
  }

  if (typeof obj === "object") {
    const properties_str = Object.entries(obj)
      .map(([key, val]) => {
        return `"${key}":${json_stringify(val)}`;
      })
      .join(",");
    return "{" + properties_str + "}";
  }
}
Salin selepas log masuk

Dengan menjalankan perkara berikut, kami dapat melihat bahawa json_stringify kami berfungsi sebagai
dijangka.

const { assert } = require("console");
const test_obj = {
  name: "John Doe",
  age: 23,
  hobbies: ["football", "comet study"]
};

assert(json_stringify(test_obj) === JSON.stringify(test_obj))
Salin selepas log masuk

Untuk menguji lebih banyak senario dan berbilang larian untuk mendapatkan idea purata tentang cara
kami skrip berjalan, kami membuat skrip ujian mudah!

Skrip ujian mudah

function validity_test(fn1, fn2, test_values) {
  for (const test_value of test_values) {
    assert(fn1(test_value) == fn2(test_value));
  }
}

function time(fn, num_runs = 1, ...args) {
  const start_time = Date.now()

  for (let i = 0; i < num_runs; i++) {
    fn(...args);
  }

  const end_time = Date.now()
  return end_time - start_time
}


function performance_test(counts) {
  console.log("Starting performance test with", test_obj);

  for (const count of counts) {
    console.log("Testing", count, "times");

    const duration_std_json = time(JSON.stringify.bind(JSON), count, test_obj);
    console.log("\tStd lib JSON.stringify() took", duration_std_json, "ms");

    const duration_custom_json = time(json_stringify, count, test_obj);
    console.log("\tCustom json_stringify() took", duration_custom_json, "ms");
  }
}

const test_obj = {} // a deeply nested JS object, ommitted here for brevity 
const test_values = [
  12,
  "string test",
  [12, 34, 1],
  [12, true, 1, false],
  test_obj
];

validity_test(JSON.stringify, json_stringify, test_values);
performance_test([1000, 10_000, 100_000, 1000_000]);
Salin selepas log masuk

Menjalankan ini, kami mendapat pemasaan seperti berikut.

Testing 1000 times
    Std lib JSON.stringify() took 5 ms
    Custom json_stringify() took 20 ms
Testing 10000 times
    Std lib JSON.stringify() took 40 ms
    Custom json_stringify() took 129 ms
Testing 100000 times
    Std lib JSON.stringify() took 388 ms
    Custom json_stringify() took 1241 ms
Testing 1000000 times
    Std lib JSON.stringify() took 3823 ms
    Custom json_stringify() took 12275 ms
Salin selepas log masuk

Ia mungkin berjalan secara berbeza pada sistem yang berbeza tetapi nisbah masa yang diambil
oleh std JSON.strngify kepada json_stringify tersuai kami hendaklah kira-kira
1:3 - 1:4

Ia mungkin berbeza juga dalam kes yang menarik. Baca terus untuk mengetahui lebih lanjut tentang
itu!

Meningkatkan prestasi

Perkara pertama yang boleh diperbaiki ialah penggunaan fungsi peta. Ia mencipta
tatasusunan baru dari yang lama. Dalam kes objek kami, ia mencipta tatasusunan
JSON merentangi sifat objek daripada tatasusunan yang mengandungi entri objek.

Perkara yang sama juga berlaku dengan rentetan elemen tatasusunan juga.

Kita perlu melingkari elemen dalam tatasusunan, atau entri objek! Tetapi
kita boleh melangkau membuat tatasusunan lain hanya untuk menyertai bahagian bertali JSON.

Berikut ialah versi yang dikemas kini (hanya bahagian yang diubah ditunjukkan untuk ringkasnya)

function json_stringify(val) {
  if (typeof val === "number" || typeof val === "boolean") {
    return String(val);
  }

  if (typeof val === "string") {
    return `"${val}"`;
  }

  if (Array.isArray(val)) {
    let elements_str = "["

    let sep = ""
    for (const element of val) {
      elements_str += sep + json_stringify(element)
      sep = ","
    }
    elements_str += "]"

    return elements_str
  }

  if (typeof val === "object") {
    let properties_str = "{"

    let sep = ""
    for (const key in val) {
      properties_str += sep + `"${key}":${json_stringify(val[key])}`
      sep = ","
    }
    properties_str += "}"

    return properties_str;
  }
}
Salin selepas log masuk

Dan inilah output skrip ujian sekarang

Testing 1000 times
        Std lib JSON.stringify() took 5 ms
        Custom json_stringify() took 6 ms
Testing 10000 times
        Std lib JSON.stringify() took 40 ms
        Custom json_stringify() took 43 ms
Testing 100000 times
        Std lib JSON.stringify() took 393 ms
        Custom json_stringify() took 405 ms
Testing 1000000 times
        Std lib JSON.stringify() took 3888 ms
        Custom json_stringify() took 3966 ms
Salin selepas log masuk

Ini kelihatan lebih baik sekarang. json_stringify tersuai kami mengambil masa hanya 3 ms
lebih daripada JSON.stringify untuk merangkai objek bersarang dalam 10,000 kali.
Walaupun ini tidak sempurna, ia adalah kelewatan yang boleh diterima.

Memicit lagi??

Kelewatan semasa mungkin disebabkan oleh semua penciptaan rentetan dan penyambungan
itu sedang berlaku. Setiap kali kami menjalankan elements_str += sep + json_stringify(elemen)
kami menggabungkan 3 tali.

Rentetan penggabungan adalah mahal kerana ia memerlukan

  1. membuat penimbal rentetan baharu agar sesuai dengan keseluruhan rentetan gabungan
  2. salin rentetan individu ke penimbal yang baru dibuat

Dengan menggunakan Penampan sendiri dan menulis data terus di sana mungkin memberi kita
peningkatan prestasi. Memandangkan kita boleh mencipta penimbal yang besar (katakan 80 aksara)
dan kemudian buat penimbal baharu untuk memuatkan 80 aksara lagi apabila ia kehabisan.

Kami tidak akan mengelak pengagihan semula / penyalinan data sama sekali, tetapi kami akan
mengurangkan operasi tersebut.

Satu lagi kelewatan yang mungkin adalah proses rekursif itu sendiri! Khususnya
panggilan fungsi yang memakan masa. Pertimbangkan panggilan fungsi kami json_stringify(val)
yang hanya mempunyai satu parameter.

Memahami panggilan Fungsi

Langkahnya ialah

  1. Tolak alamat pemulangan ke tindanan
  2. tolak rujukan hujah ke timbunan
  3. Dalam fungsi yang dipanggil
    1. Pancarkan rujukan parameter daripada tindanan
    2. Pancarkan alamat pemulangan daripada timbunan
    3. tolak nilai pulangan (bahagian bertali) pada tindanan
  4. Dalam fungsi panggilan
    1. Pati keluar nilai yang dikembalikan oleh fungsi daripada tindanan

Semua operasi ini berlaku untuk memastikan panggilan fungsi berlaku dan ini menambah CPU
kos.

Jika kami mencipta algoritma bukan rekursif json_stringify semua operasi ini
yang disenaraikan di atas untuk panggilan fungsi (kali bilangan panggilan tersebut) ialah
dikurangkan kepada tiada.

Ini boleh menjadi percubaan masa hadapan.

Perbezaan versi NodeJs

Satu perkara terakhir yang perlu diperhatikan di sini. Pertimbangkan output skrip ujian
berikut

Testing 1000 times
        Std lib JSON.stringify() took 8 ms
        Custom json_stringify() took 8 ms
Testing 10000 times
        Std lib JSON.stringify() took 64 ms
        Custom json_stringify() took 51 ms
Testing 100000 times
        Std lib JSON.stringify() took 636 ms
        Custom json_stringify() took 467 ms
Testing 1000000 times
        Std lib JSON.stringify() took 6282 ms
        Custom json_stringify() took 4526 ms
Salin selepas log masuk

Adakah json_stringify tersuai kami hanya berprestasi lebih baik daripada standard NodeJs
JSON.stringify???

Baiklah ya! Tetapi ini adalah versi lama NodeJs (v18.20.3). Ternyata, untuk
versi ini (dan lebih rendah juga mungkin) json_stringify buatan kami berfungsi
lebih pantas daripada perpustakaan standard!

Semua ujian untuk artikel ini (kecuali yang terakhir ini) telah dilakukan dengan
Nod v22.6.0

Prestasi JSON.stringify telah meningkat daripada v18 kepada v22. Ini sangat hebat

Perlu juga ambil perhatian bahawa, skrip kami berprestasi lebih baik dalam NodeJs v22.
Jadi, ini bermakna, NodeJs telah meningkatkan prestasi keseluruhan masa jalan juga.
Kemungkinan kemas kini telah berlaku pada enjin V8 yang mendasari itu sendiri.

Nah, ini merupakan pengalaman yang menyeronokkan untuk saya. Dan saya harap ia akan menjadi untuk
awak juga. Dan di tengah-tengah semua keseronokan ini, kami belajar satu atau dua perkara!

Teruskan membina, teruskan menguji!

Atas ialah kandungan terperinci Bersaing dengan JSON.stringify - dengan membina yang tersuai. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

<🎜>: Bubble Gum Simulator Infinity - Cara Mendapatkan dan Menggunakan Kekunci Diraja
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Sistem Fusion, dijelaskan
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers of the Witch Tree - Cara Membuka Kunci Cangkuk Bergelut
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Tutorial Java
1671
14
Tutorial PHP
1276
29
Tutorial C#
1256
24
Python vs JavaScript: Keluk Pembelajaran dan Kemudahan Penggunaan Python vs JavaScript: Keluk Pembelajaran dan Kemudahan Penggunaan Apr 16, 2025 am 12:12 AM

Python lebih sesuai untuk pemula, dengan lengkung pembelajaran yang lancar dan sintaks ringkas; JavaScript sesuai untuk pembangunan front-end, dengan lengkung pembelajaran yang curam dan sintaks yang fleksibel. 1. Sintaks Python adalah intuitif dan sesuai untuk sains data dan pembangunan back-end. 2. JavaScript adalah fleksibel dan digunakan secara meluas dalam pengaturcaraan depan dan pelayan.

Dari C/C ke JavaScript: Bagaimana semuanya berfungsi Dari C/C ke JavaScript: Bagaimana semuanya berfungsi Apr 14, 2025 am 12:05 AM

Peralihan dari C/C ke JavaScript memerlukan menyesuaikan diri dengan menaip dinamik, pengumpulan sampah dan pengaturcaraan asynchronous. 1) C/C adalah bahasa yang ditaip secara statik yang memerlukan pengurusan memori manual, manakala JavaScript ditaip secara dinamik dan pengumpulan sampah diproses secara automatik. 2) C/C perlu dikumpulkan ke dalam kod mesin, manakala JavaScript adalah bahasa yang ditafsirkan. 3) JavaScript memperkenalkan konsep seperti penutupan, rantaian prototaip dan janji, yang meningkatkan keupayaan pengaturcaraan fleksibiliti dan asynchronous.

JavaScript dan Web: Fungsi teras dan kes penggunaan JavaScript dan Web: Fungsi teras dan kes penggunaan Apr 18, 2025 am 12:19 AM

Penggunaan utama JavaScript dalam pembangunan web termasuk interaksi klien, pengesahan bentuk dan komunikasi tak segerak. 1) kemas kini kandungan dinamik dan interaksi pengguna melalui operasi DOM; 2) pengesahan pelanggan dijalankan sebelum pengguna mengemukakan data untuk meningkatkan pengalaman pengguna; 3) Komunikasi yang tidak bersesuaian dengan pelayan dicapai melalui teknologi Ajax.

JavaScript in Action: Contoh dan projek dunia nyata JavaScript in Action: Contoh dan projek dunia nyata Apr 19, 2025 am 12:13 AM

Aplikasi JavaScript di dunia nyata termasuk pembangunan depan dan back-end. 1) Memaparkan aplikasi front-end dengan membina aplikasi senarai TODO, yang melibatkan operasi DOM dan pemprosesan acara. 2) Membina Restfulapi melalui Node.js dan menyatakan untuk menunjukkan aplikasi back-end.

Memahami Enjin JavaScript: Butiran Pelaksanaan Memahami Enjin JavaScript: Butiran Pelaksanaan Apr 17, 2025 am 12:05 AM

Memahami bagaimana enjin JavaScript berfungsi secara dalaman adalah penting kepada pemaju kerana ia membantu menulis kod yang lebih cekap dan memahami kesesakan prestasi dan strategi pengoptimuman. 1) aliran kerja enjin termasuk tiga peringkat: parsing, penyusun dan pelaksanaan; 2) Semasa proses pelaksanaan, enjin akan melakukan pengoptimuman dinamik, seperti cache dalam talian dan kelas tersembunyi; 3) Amalan terbaik termasuk mengelakkan pembolehubah global, mengoptimumkan gelung, menggunakan const dan membiarkan, dan mengelakkan penggunaan penutupan yang berlebihan.

Python vs JavaScript: Komuniti, Perpustakaan, dan Sumber Python vs JavaScript: Komuniti, Perpustakaan, dan Sumber Apr 15, 2025 am 12:16 AM

Python dan JavaScript mempunyai kelebihan dan kekurangan mereka sendiri dari segi komuniti, perpustakaan dan sumber. 1) Komuniti Python mesra dan sesuai untuk pemula, tetapi sumber pembangunan depan tidak kaya dengan JavaScript. 2) Python berkuasa dalam bidang sains data dan perpustakaan pembelajaran mesin, sementara JavaScript lebih baik dalam perpustakaan pembangunan dan kerangka pembangunan depan. 3) Kedua -duanya mempunyai sumber pembelajaran yang kaya, tetapi Python sesuai untuk memulakan dengan dokumen rasmi, sementara JavaScript lebih baik dengan MDNWebDocs. Pilihan harus berdasarkan keperluan projek dan kepentingan peribadi.

Python vs JavaScript: Persekitaran dan Alat Pembangunan Python vs JavaScript: Persekitaran dan Alat Pembangunan Apr 26, 2025 am 12:09 AM

Kedua -dua pilihan Python dan JavaScript dalam persekitaran pembangunan adalah penting. 1) Persekitaran pembangunan Python termasuk Pycharm, Jupyternotebook dan Anaconda, yang sesuai untuk sains data dan prototaip cepat. 2) Persekitaran pembangunan JavaScript termasuk node.js, vscode dan webpack, yang sesuai untuk pembangunan front-end dan back-end. Memilih alat yang betul mengikut keperluan projek dapat meningkatkan kecekapan pembangunan dan kadar kejayaan projek.

Peranan C/C dalam JavaScript Jurubah dan Penyusun Peranan C/C dalam JavaScript Jurubah dan Penyusun Apr 20, 2025 am 12:01 AM

C dan C memainkan peranan penting dalam enjin JavaScript, terutamanya digunakan untuk melaksanakan jurubahasa dan penyusun JIT. 1) C digunakan untuk menghuraikan kod sumber JavaScript dan menghasilkan pokok sintaks abstrak. 2) C bertanggungjawab untuk menjana dan melaksanakan bytecode. 3) C melaksanakan pengkompil JIT, mengoptimumkan dan menyusun kod hot-spot semasa runtime, dan dengan ketara meningkatkan kecekapan pelaksanaan JavaScript.

See all articles