Currently we convert objects to strings using `'' + value` which is quickest, but it stringifies the value using its `valueOf`, rather than `toString`. These changes switch to using `String(value)` which has identical performance and calls the `toString` method as expected. Note that another option was calling `toString` directly, but benchmarking showed it to be slower. I've included the benchmark I used to verify the performance so we have it for future reference and we can reuse it when making changes to `renderStringify` in the future. Also for reference, here are the results of the benchmark: ``` Benchmark: renderStringify concat: 2.006 ns(0%) concat with toString: 2.201 ns(-10%) toString: 237.494 ns(-11741%) toString with toString: 121.072 ns(-5937%) constructor: 2.201 ns(-10%) constructor with toString: 2.201 ns(-10%) toString mono: 14.536 ns(-625%) toString with toString mono: 9.757 ns(-386%) ``` Fixes #38839. PR Close #39843
		
			
				
	
	
		
			271 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			271 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| package(default_visibility = ["//visibility:private"])
 | |
| 
 | |
| load("//tools:defaults.bzl", "jasmine_node_test", "ng_benchmark", "ng_rollup_bundle", "ts_library")
 | |
| 
 | |
| ts_library(
 | |
|     name = "perf_lib",
 | |
|     srcs = glob(
 | |
|         ["**/*.ts"],
 | |
|     ),
 | |
|     deps = [
 | |
|         "//packages/core",
 | |
|         "//packages/core/src/util",
 | |
|         "@npm//@types/jasmine",
 | |
|         "@npm//@types/node",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| jasmine_node_test(
 | |
|     name = "perf",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "class_binding_lib",
 | |
|     entry_point = ":class_binding/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "class_binding",
 | |
|     bundle = ":class_binding_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "directive_inputs_lib",
 | |
|     entry_point = ":directive_inputs/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "directive_inputs",
 | |
|     bundle = ":directive_inputs_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "directive_instantiate_lib",
 | |
|     entry_point = ":directive_instantiate/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "directive_instantiate",
 | |
|     bundle = ":directive_instantiate_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "element_text_create_lib",
 | |
|     entry_point = ":element_text_create/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "element_text_create",
 | |
|     bundle = ":element_text_create_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "interpolation_lib",
 | |
|     entry_point = ":interpolation/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "interpolation",
 | |
|     bundle = ":interpolation_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "listeners_lib",
 | |
|     entry_point = ":listeners/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "listeners",
 | |
|     bundle = ":listeners_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "noop_change_detection_lib",
 | |
|     entry_point = ":noop_change_detection/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "noop_change_detection",
 | |
|     bundle = ":noop_change_detection_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "ng_template_lib",
 | |
|     entry_point = ":ng_template/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "ng_template",
 | |
|     bundle = ":ng_template_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "property_binding_lib",
 | |
|     entry_point = ":property_binding/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "property_binding",
 | |
|     bundle = ":property_binding_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "property_binding_update_lib",
 | |
|     entry_point = ":property_binding_update/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "property_binding_update",
 | |
|     bundle = ":property_binding_update_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "style_binding_lib",
 | |
|     entry_point = ":style_binding/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "style_binding",
 | |
|     bundle = ":style_binding_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "style_and_class_bindings_lib",
 | |
|     entry_point = ":style_and_class_bindings/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "style_and_class_bindings",
 | |
|     bundle = ":style_and_class_bindings_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "map_based_style_and_class_bindings_lib",
 | |
|     entry_point = ":map_based_style_and_class_bindings/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "map_based_style_and_class_bindings",
 | |
|     bundle = ":map_based_style_and_class_bindings_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "duplicate_style_and_class_bindings_lib",
 | |
|     entry_point = ":duplicate_style_and_class_bindings/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "duplicate_style_and_class_bindings",
 | |
|     bundle = ":duplicate_style_and_class_bindings_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "duplicate_map_based_style_and_class_bindings_lib",
 | |
|     entry_point = ":duplicate_map_based_style_and_class_bindings/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "duplicate_map_based_style_and_class_bindings",
 | |
|     bundle = ":duplicate_map_based_style_and_class_bindings_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "host_binding_lib",
 | |
|     entry_point = ":host_binding/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "host_binding",
 | |
|     bundle = ":host_binding_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "i18n_lib",
 | |
|     entry_point = ":i18n/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "i18n",
 | |
|     bundle = ":i18n_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "view_destroy_hook_lib",
 | |
|     entry_point = ":view_destroy_hook/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "view_destroy_hook",
 | |
|     bundle = ":view_destroy_hook_lib",
 | |
| )
 | |
| 
 | |
| ng_rollup_bundle(
 | |
|     name = "render_stringify_lib",
 | |
|     entry_point = ":render_stringify/index.ts",
 | |
|     deps = [
 | |
|         ":perf_lib",
 | |
|     ],
 | |
| )
 | |
| 
 | |
| ng_benchmark(
 | |
|     name = "render_stringify",
 | |
|     bundle = ":render_stringify_lib",
 | |
| )
 |