Performance of Java versus C++

常见的AXI总线仲裁器概述-AXI协议理解(一) SoC 设计广泛采用共享总线式的片上通信,其中的仲裁器是共享总线的关键技术之一。AMBA AXI 总线协议以高性能、高频率的系统设计为目标,适合高带宽、低延迟的系统设计,可以达到高频率的操作而不需要复杂的总线桥,满足众多部件的接口要求,具备高度灵活的互联结构,并且向后兼容 AHB 和 APB 接口。 阅读详情

Performance of Java versus C++

J.P.Lewis and Ulrich Neumann
Computer Graphics and Immersive Technology Lab
University of Southern California

www.idiom.com/~zilla

Jan. 2003
updated 2004

[also see this FAQ]


This article surveys a number of benchmarks and finds that Java performance on numerical code is comparable to that of C++, with hints that Java's relative performance is continuing to improve. We then describe clear theoretical reasons why these benchmark results should be expected.

Benchmarks

Five composite benchmarks listed below show that modern Java has acceptable performance, being nearly equal to (and in many cases faster than) C/C++ across a number of benchmarks.

  1. Numerical Kernels

    Benchmarking Java against C and Fortran for Scientific Applications
    Mark Bull, Lorna Smith, Lindsay Pottage, Robin Freeman,
    EPCC, University of Edinburgh (2001).

    The authors test some real numerical codes (FFT, Matrix factorization, SOR, fluid solver, N-body) on several architectures and compilers. On Intel they found that the Java performance was very reasonable compared to C (e.g, 20% slower), and that Java was faster than at least one C compiler (KAI compiler on Linux).

    The authors conclude, "On Intel Pentium hardware, especially with Linux, the performance gap is small enough to be of little or no concern to programmers."

  2. More numerical methods: SciMark2 scores

    R. F. Boisvert, J. Moriera, M. Phillipsen, R. Pozo,
    Java and Numerical Computing,
    Computing in Science & Engineering, 3(2):18-24, Mar.-Apr., 2001.

    SciMark includes a number of numerical codes. On a PIII/500, MFlops (higher is better):

    ibm jdk 1.3.0 84.5
    linux2.2 gcc (2.9x) -O6 87.1
  3. Still more numerical methods
    From the book Object-Oriented Implementations of Numerical Methods by Didier Besset (MorganKaufmann, 2001):

    OperationUnitsCSmalltalkJava
    Polynomial 10th degreemsec.1.127.79.0
    Neville Interpolation (20 points)msec.0.911.00.8
    LUP matrix inversion (100 x 100)sec.3.922.91.0

  4. Microbenchmarks (cache effects considered)

    Several years ago these benchmarks showed java performance at the time to be somewhere in the middle of C compiler performance - faster than the worst C compilers, slower than the best. These are "microbenchmarks", but they do have the advantage that they were run across a number of different problem sizes and thus the results are not reflecting a lucky cache interaction (see more details on this issue in the next section).

    These benchmarks were updated with a more recent java(1.4) and gcc(3.2), using full optimization (gcc -O3 -mcpu=pentiumpro -fexpensive-optimizations -fschedule-insns2...). This time java is faster than C the majority of the tests, by a factor of more than 2 in some cases...

    ... suggesting that java performance is catching up to or even pulling ahead of gcc at least.

    These test were mostly integer (except for an FFT).

  5. Microbenchmarks (cache effects not considered)
    In January 2004 OSNews.com posted an article, Nine Language Performance Round-up: Benchmarking Math & File I-O. These are simple numeric and file I/O loops, and no doubt suffer from the arbitrary cache interaction factor described below. They were however run under several different compilers, which helps. Again Java is competitive with (actually slighty faster than) several C++ compilers including Visual C++ in the majority of the benchmarks.

    (One exceptional benchmark tested trigonometry library calls. Java numerical programmers are aware that these calls became slower in java 1.4; recent benchmarks suggest this issue was fixed in java 1.4.2)

Note that these benchmarks are on Intel architecture machines. Java compilers on some other processors are less developed at present.

And In Theory: Maybe Java Should be Faster

Java proponents have stated that Java will soon be faster than C. Why? Several reasons (also see reference [1]):

1) Pointers make optimization hard

This is a reason why C is generally a bit slower than Fortran.

In C, consider the code

        x = y + 2 * (...)
        *p = ...
	arr[j] = ...
        z = x + ...
Because p could be pointing at x, a C compiler cannot keep x in a register and instead has to write it to cache and read it back -- unless it can figure out where p is pointing at compile time. And because arrays act like pointers in C/C++, the same is true for assignment to array elements: arr[j] could also modify x.

This pointer problem in C resembles the array bounds checking issue in Java: in both cases, if the compiler can determine the array (or pointer) index at compile time it can avoid the issue.

In the loop below, for example, a Java compiler can trivially avoid testing the lower array bound because the loop counter is only incremented, never decremented. A single test before starting the loop handles the upper bound test if 'len' is not modified inside the loop (and java has no pointers, so simply looking for an assignment is enough to determine this):

   for( int i = 0; i < len; i++ ) { a[i] = ... }

In cases where the compiler cannot determine the necessary information at compile time, the C pointer problem may actually be the bigger performance hit. In the java case, the loop bound(s) can be kept in registers, and the index is certainly in a register, so a register-register test is needed. In the C/C++ case a load from memory is needed.

2) Garbage collection- is it worse...or better?

Most programmers say garbage collection is or should be slow, with no given reason- it's assumed but never discussed. Some computer language researchers say otherwise.

Consider what happens when you do a new/malloc: a) the allocator wanders through some lists looking for a slot of the right size, then returns you a pointer. b) This pointer is pointing to some pretty random place.

With GC, a) the allocator doesn't need to look for memory, it knows where it is, b) the memory it returns is adjacent to the last bit of memory you requested. The wandering around part happens not all the time but only at garbage collection. And then (depending on the GC algorithm) things get moved of course as well.

The cost of missing the cache

The big benefit of GC is memory locality. Because newly allocated memory is adjacent to the memory recently used, it is more likely to already be in the cache.

How much of an effect is this? One rather dated (1993) example shows that missing the cache can be a big cost: changing an array size in small C program from 1023 to 1024 results in a slowdown of 17 times (not 17%). This is like switching from C to VB! This particular program stumbled across what was probably the worst possible cache interaction for that particular processor (MIPS); the effect isn't that bad in general...but with processor speeds increasing faster than memory, missing the cache is probably an even bigger cost now than it was then.

(It's easy to find other research studies demonstrating this; here's one from Princeton: they found that (garbage-collected) ML programs translated from the SPEC92 benchmarks have lower cache miss rates than the equivalent C and Fortran programs.)

This is theory, what about practice? In a well known paper [2] several widely used programs (including perl and ghostscript) were adapted to use several different allocators including a garbage collector masquerading as malloc (with a dummy free()). The garbage collector was as fast as a typical malloc/free; perl was one of several programs that ran faster when converted to use a garbage collector. Another interesting fact is that the cost of malloc/free is significant: both perl and ghostscript spent roughly 25-30% of their time in these calls.

Besides the improved cache behavior, also note that automatic memory management allows escape analysis, which identifies local allocations that can be placed on the stack. (Stack allocations are clearly cheaper than heap allocation of either sort).

3) Run-time compilation

The JIT compiler knows more than a conventional "pre-compiler", and it may be able to do a better job given the extra information:

  • The compiler knows what processor it is running on, and can generate code specifically for that processor. It knows whether (for example) the processor is a PIII or P4, if SSE2 is present, and how big the caches are. A pre-compiler on the other hand has to target the least-common-denominator processor, at least in the case of commercial software.

  • Because the compiler knows which classes are actually loaded and being called, it knows which methods can be de-virtualized and inlined. (Remarkably, modern java compilers also know how to "uncompile" inlined calls in the case where an overriding method is loaded after the JIT compilation happens.)

  • A dynamic compiler may also get the branch prediction hints right more often than a static compiler.


It might also be noted that Microsoft has some similar comments regarding C# performance [5]:
  • "Myth: JITed Programs Execute Slower than Precompiled Programs"

  • .NET still provides a traditional pre-compiler ngen.exe, but "since the run-time only optimizations cannot be provided... the code is usually not as good as that generated by a normal JIT."

Speed and Benchmark Issues

Benchmarks usually lead to extensive and heated discussion in popular web forums. From our point of view there are several reasons why such discussions are mostly "hot air".

What is slow?

The notion of "slow" in popular discussions is often poorly calibrated. If you write a number of small benchmarks in several different types of programming language, the broad view of performance might be something like this:

Language classtypical slowdown
Assembler:1
Low level compiled (Fortran, C):1-2
Byte-code (python):25-50
Interpreted strings (csh, tcl?):250x

Despite this big picture, performance differences of less than a factor of two are often upheld as evidence in speed debates. As we describe next, differences of 2x-4x or more are often just noise.

Don't characterize the speed of a language based on a single benchmark of a single program.

We often see people drawing conclusions from a single benchmark. For example, an article posted on slashdot.org [3] claims to address the question "Which programming language provides the fastest tool for number crunching under Linux?", yet it discussed only one program.

Why isn't one program good enough?

For one, it's common sense; the compiler may happen to do particularly well or particularly poorly on the inner loop of the program; this doesn't generalize. The fourth set of benchmarks above show Java as being faster than C by a factor two on an FFT of an array of a particular size. Should you now proclaim that Java is always twice as fast as C? No, it's just one program.

There is a more important issue than the code quality on the particular benchmark, however:

Cache/Memory effects.

Look at the FFT microbenchmark that we referenced above. The figure is reproduced here with permission:

On this single program, depending on the input size, the relative performance of 'IBM' (IBM's Java) varies from about twice as slow to twice as fast as 'max-C' (gcc) (-O3 -lm -s -static -fomit-frame-pointer -mpentiumpro -march=pentiumpro -malign-functions=4 -fu nroll-all-loops -fexpensive-optimizations -malign-double -fschedule-insns2 -mwide-multiply -finline-function s -fstrict-aliasing). So what do we conclude from this benchmark? Java is twice as fast as C, or twice as slow, or ...

This performance variation due to factors of data placement and size is universal. A more dramatic example of such cache effects is the link mentioned in the discussion on garbage collection above.

The person who posted [3] demonstrated the fragility of his own benchmark in a followup post, writing that "Java now performs as well as gcc on many tests" after changing something (note that it was not the Java language that changed).

Conclusions: Why is "Java is Slow" so Popular?

Java is now nearly equal to (or faster than) C++ on low-level and numeric benchmarks. This should not be surprising: Java is a compiled language (albeit JIT compiled).

Nevertheless, the idea that "java is slow" is widely believed. Why this is so is perhaps the most interesting aspect of this article.

Let's look at several possible reasons:

  • Java circa 1995 was slow. The first incarnations of java did not java a JIT compiler, and hence were bytecode interpreted (like Python for example). JIT compilers appeared in JVMs from Microsoft, Symantec, and in Sun's java1.2.

    This explanation is implausible. Most "computer folk" are able to rattle off the exact speed in GHz of the latest processors, and they track this information as it changes each month (and have done so for years). Yet this explanation asks us to believe that they are not able to remember that a single and rather important language speed change occurred in 1996.

  • Java can be slow still. For example, programs written with the thread-safe Vector class are necessarily slower (on a single processor at least) than those written with the equivalent thread-unsafe ArrayList class.

    This explanation is equally unsatisfying, because C++ and other languages have similar "abstraction penalties". For example, The Kernighan and Pike book The Practice of Programming has a table with the following entries, describing the performance of several implementations of a text processing program:

    Version400 MHz PII
    C0.30 sec
    C++/STL/deque11.2 sec
    C++/STL/list1.5 sec

    Another evidently well known problem in C++ is the overhead of returning an object from a function (several unnecessary object create/copy/destruct cycles are involved).

  • Java program startup is slow. As a java program starts, it unzips the java libraries and compiles parts of itself, so an interactive program can be sluggish for the first couple seconds of use.

    This approaches being a reasonable explanation for the speed myth. But while it might explain user's impressions, it does not explain why many programmers (who can easily understand the idea of an interpreted program being compiled) share the belief.

Two of the most interesting observations regarding this issue are that:
  1. there is a similar "garbage collection is slow" myth that persists despite decades of evidence to the contrary, and
  2. that in web flame wars, people are happy to discuss their speed impressions for many pages without ever referring to actual data.
Together these suggest that it is possible that no amount of data will alter peoples' beliefs, and that in actuality these "speed beliefs" probably have little to do with java, garbage collection, or the otherwise stated subject. Our answer probably lies somewhere in sociology or psychology. Programmers, despite their professed appreciation of logical thought, are not immune to a kind of mythology, though these particular "myths" are arbitrary and relatively harmless.

Acknowledgements

Ian Rogers and Curt Fischer clarified some points.

References

[1] K. Reinholtz, Java will be faster than C++, ACM Sigplan Notices, 35(2): 25-28 Feb 2000.

[2] Benjamin Zorn, The Measured Cost of Conservative Garbage Collection Software - Practice and Experience 23(7): 733-756, 1992.

[3] Linux Number Crunching: Languages and Tools, referenced on slashdot.org

[4] Christopher W. Cowell-Shah, Nine Language Performance Round-up: Benchmarking Math & File I/O, appeared at OSnews.com, Jan. 2004.

[5] E. Schanzer, Performance Considerations for Run-Time Technologies in the .NET Framework, Microsoft Developer Network article.

导航系统 | 全球四大卫星导航系统(2025)核心能力对比分析 北斗系统通过GEO卫星(80°E、110.5°E、140°E)实现区域增强,其IGSO卫星在亚太地区形成"8"字形轨迹,使该区域可见卫星数量比GPS多4-6颗,显著提升复杂环境下的定位可用性[13]。北斗短报文功能在2025年云南地震救援中发挥关键作用,被困人员通过北斗终端发送120字求救信息,实现"位置+状态"一体化上报,救援响应时间缩短40%[15]。北斗通过三频信号(B1C/B2a/B3)消除电离层延迟误差,在城市峡谷环境下定位连续性达99.98%,优于GPS的99.95%[5]。 阅读详情

相关推荐

【UE5+Quest3】手部模型替换---3-0

这次手部模型替换遇到了一些小问题,不过好在是bug一个个都处理掉了,我会分开几个章节去整理。详细的视频教程可以参考油管大佬的视频手部素材放到文章末尾,自行下载使用。(仅用作学习研究,不可用于商用)

qbbmnnnnnn的博客 944

[ZT]Performance of Java versus C++

Performance of Java versus C++ On the Persistence of (Java) Performance Myths -->J.P.Lewis and Ulrich Neumann Computer Graphics and Immersive Technology Lab University of Southern California www.id

墟 2538

嵌入式Linux网络调试:YT8531/YT8521 PHY驱动移植与设备树配置避坑指南

本文深入解析嵌入式Linux系统中YT8531/YT8521 PHY驱动移植与设备树配置的关键技术,涵盖内核驱动适配、RGMII接口时序调整及常见问题排查。针对Motorcomm千兆以太网PHY芯片,提供详细的设备树配置示例和调试技巧,帮助开发者规避典型设计陷阱,确保网络功能稳定运行。

weixin_42525632的博客 673

Java versus C++ Performance

Recently, I came across an interesting discussion of C++ versus Java performance over on Stack Exchange. There was also somegood discussion of the article on Reddit which included a link to an i

门没锁的专栏 862

LightTools 中LCD投影仿真的checkerboard pattern偏振控制技术解析

本文深入解析了在LightTools软件中进行LCD投影仿真时,利用checkerboard pattern(棋盘格图案)结合偏振控制技术来模拟液晶面板像素开关、提升图像对比度的核心方法。文章从实战角度出发,详细拆解了通过设置波片(如1/2波片)和偏振片来操控S光与P光转换的原理,并分享了在LightTools中搭建仿真模型、使用VBA脚本自动化配置参数以提高效率的实用技巧,为光学工程师优化投影系统仿真流程提供了清晰指导。

weixin_29305313的博客 344

华硕笔记本+Ubuntu 20.04:用cpupower解决Intel CPU频率上不去/功耗墙问题实战

本文详细介绍了在华硕笔记本Ubuntu 20.04系统下使用cpupower工具解决Intel CPU频率受限和功耗墙问题的实战方法。通过禁用Intel P-State驱动、配置userspace模式以及高级调优技巧,帮助用户突破性能瓶颈,提升编译和计算效率。

weixin_42561476的博客 523

C# versus C++ versus Java performance comparison

The performance comparison of C#, Java and C++ was always a controversial subject. Many people who are unfamiliar with JIT'ed environments claimed anything runs on JIT is too slow compared to C++. On ...

weixin_34138056的博客 101

海康VisionMaster零代码开发实战:从PLC工程师到视觉专家的捷径

本文为PLC工程师提供了利用海康VisionMaster视觉平台实现零代码视觉开发的实战指南。文章详细阐述了如何通过图形化流程设计替代传统编程,快速搭建视觉检测应用,并实现与PLC的无缝通讯,是工程师从设备控制迈向视觉系统集成的有效捷径。

weixin_29201859的博客 293

CPU 缓存 | 原理、映射、一致性

……

u013669912的博客 410

以 DeleteRestrictions 与 inlineDelete 为核心的 Fiori Elements 表格删除机制全解

SAP Fiori elements 中删除操作的设计与实现涉及多维度考量。框架默认依据 OData 元数据判断删除能力,通过 DeleteRestrictions 注解实现行级条件控制(deletable-path)。表格支持两种删除模式:工具栏集中删除与响应式表格行内删除,但二者不建议混用。关键约束包括:行内删除仅适用于 Responsive Table,且与多选功能互斥。配置需遵循三层架构:后端能力注解、前端表格形态和运行时交互。设计上强调禁用优于隐藏的可用性原则,并需保持列表页与对象页的删除体验一致

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 153

使用菱FX5U系列PLC实现以太网通信的具体方法示例

接下来,我们将创建一个简单的CPU通信功能,以实现与其他设备的以太网通信。在上述代码中,我们首先设置访问号,然后创建一个数据读取命令(M_READ)和一个数据写入命令(M_WRITE)。此外,在实际应用中,您还需要确保PLC和其他设备之间的网络连接正常,并且遵循相应的通信协议。在上述代码中,我们执行了数据读取命令,并将接收到的响应存储在M_RESPONSE变量中。通过简单CPU通信功能,菱FX5U系列PLC可以实现与其他设备的以太网通信。我们将提供相应的源代码和详细的说明,以帮助您轻松实现这一功能。

DevCyberX的博客 1525

虚拟内存 | 原理、硬件地址转换、运行机制与 Linux 应用

……

u013669912的博客 356

PS射击游戏射线检测优化:原理、工程与全链路高性能实现

射线池:减少GC,提升批量检测效率。分层检测:先粗后细,远距离射击高效判定。批量检测:并行处理,适合大量射线场景。空间结构:进一步加速大场景检测。下面继续深入射线检测优化,补充更多实用细节和进阶技巧,包括空间分区加速、射线检测多线程/异步化、射线合并与分帧、射线池通用模板、常见性能陷阱与调优建议等。对于极端性能需求,可自定义轻量级物理系统,仅检测关键对象(如玩家、子弹),跳过复杂物理引擎。结合AABB、OBB、球体等简单碰撞体,射线-包围体检测极快。空间分区+分层检测是大场景射线优化核心。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 434

简单的网页关键词匹配工具

简单的网页关键词匹配工具作者:Monica Pawlan2003年7月 你是否曾经使用大量的详细信息创建网页,然后希望读者可以使用一种简单的方法,根据特定于用户的关键词分析和进入相应页面?本文解释了如何使用HTML表单和JSP技术来正确地实现上述要求。即使你从没希望得到这种效果,你可能也会发现本文的演示例子和代码练习十分有用,因为这些例子和代码涵盖了如何检索请求的值,并将这些值与静态文件中

fraternity_java的专栏 2409

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

使用JFreeReport生成报表

使用JFreeReport生成报表作者:肖菁文章摘要JFreeReport用于生成报表。JFreeReport的数据继承自Swing组件的TableModel接口,使用基于XML的报表格式定义文件对报表进行格式化。JFreeReport生成的报表可以分页预览、打印或者保存为多种格式的文件如pdf、Excel、html等。作者在本文中详细的介绍了如何定义报表格式定义文件、如何使用JF

fraternity_java的专栏 2144

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Weighing in on Java native compilation

Weighing in on Java native compilationContents:Code compilation basicsAbout the test setupTest 1: Prime.java

fraternity_java的专栏 1800

Java Performance: the top 5 pigs

  Home    Books    Boards    Newsletter    Resources    About    ContactsJava Performance: the top 5 pigs(from September Bitter Java newsletter)I recently com

fraternity_java的专栏 1151

SOA 比 Web Services 涵义更广

标题:SOA 比 Web Services 涵义更广 浏览次数: 12 时间:2004-08-31作者:Steve Wilkes无论何时在街上问一个了解点技术的普通人有关面向服务的架构(SOA)的概念,首先反应到他的头脑中的东西将是Web Services。尽管SOA已经存在一段

fraternity_java的专栏 1115

Design Patterns 入門 - 職責鏈(Chain of Responsibility) [精華]

Design Patterns 入門 - 職責鏈(Chain of Responsibility) [精華] 其實職責鏈(Chain of Responsibility)的概念,即使是一個剛學程式設計的新手也會用到,一個簡單的 if...else if ... else 流程控制就有職責鏈的概念:if(/* 符合請求條件一 */) // 執行請求一el

fraternity_java的专栏 1048

JSP学习心得

标题:JSP学习心得 浏览次数: 1443 时间:2003-08-30作者:徐春金下面是本人在学习JSP时的一些心得: 一、JSP工作原理在一个JSP文件第一次被请求时,JSP引擎把该JSP文件转换成为一个servlet。而这个引擎本身也是一个servlet,在JSWDK

fraternity_java的专栏 1045

测试J2EE Web Services

标题:测试J2EE Web Services 浏览次数: 46 时间:2004-08-31作者:Abhijit Patil 和 Seetharam Param我们已经了解了很多关于Web Services开发方面的知识,而对于Web Services测试所面临的挑战却知之甚少。本

fraternity_java的专栏 1031

用JAVA访问共享文件系统

用JAVA访问共享文件系统作者:薛谷雨前言在Microsoft 网 络 系 统 中,SMB(Server Message Block, 服 务 信 息 块) 协 议 是Windows for Workgroup(WfWg)、Windows 95、Windows NT 和LanManager 用 来 实 现 共 享 局 域 网 上 文 件 和 打 印 机 的 协 议。 对 于 利 用

fraternity_java的专栏 926

12个最重要的J2EE最佳实践(一)

12个最重要的J2EE最佳实践(一) 作者:Kyle Brown, Keys Botzum, Ruth Willenborg 发文时间:2004.07.15为了不使问题复杂化,我们就使用——最重要的 12个 J2EE 最佳实践…… 最佳实践 1、始终使用 MVC 框架。2、在每一层都应用自动单元测试和测试管理。 3、按照规范来进行开发,而不是按照应用服务

fraternity_java的专栏 794

用jsp动态输出excel文档和中文乱码问题的解决

用jsp动态输出excel文档和中文乱码问题的解决作者:陈万飞最近在网上看到一个用java来操纵excel的open source,在weblogic上试用了一下,觉得很不错,特此向大家推荐一下。首先去http://www.andykhan.com/jexcelapi/index.html下载最新的JExcelApi,把jxl.jar置于你的classpath中。写一个ja

fraternity_java的专栏 762

J2EE 1.4 的新特性

标题:J2EE 1.4 的新特性:概述 浏览次数: 1027 时间:2004-04-29作者:Dave LandersJ2EE开发人员所需掌握的技术列表是相当冗长的。在这篇文章里,我们不会讨论J2EE技术,甚至也不会讨论新技术。我们将要探讨的是它的一些主要的新特性,然后您就会知道

fraternity_java的专栏 744
上一篇: 用Machin公式计算圆周率的源程序
下一篇: Java Performance: the top 5 pigs
fraternity_java
博客等级 码龄22年 1粉丝 30原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值