Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: For values of "Bytes transferred" and "Bytes/s" with 1000-based prefix names use 1000-based divisor instead of 1024-based #248

Merged
merged 1 commit into from Mar 23, 2021

Conversation

ghost
Copy link

@ghost ghost commented Mar 13, 2021

v.0.21.0

I saw in the GUI peer window in the "received" column 1007 KB, and after increasing to >=1024 I guess, it switched to 1 MB. I would have expected the display unit to change from KB to MB already at value >=1000.

I looked into the code, and the values appear to be power-of-2 byte values, so the switching at >=1024 and not >=1000 seems correct.
But the unit display is not precisely correct, binary prefixes should be used for power-of-2 byte values.

To be correct, this PR changes KB/MB/GB to KiB/MiB/GiB. KB to kB and the divisor from 1024 to 1000.

@ghost
Copy link
Author

ghost commented Mar 13, 2021

This is how it looks with this PR applied: Edit: outdated
bildschirmfoto
bildschirmfoto

@@ -762,11 +762,11 @@ QString formatBytes(uint64_t bytes)
if(bytes < 1024)
return QString(QObject::tr("%1 B")).arg(bytes);
if(bytes < 1024 * 1024)
return QString(QObject::tr("%1 KB")).arg(bytes / 1024);
return QString(QObject::tr("%1 KiB")).arg(bytes / 1024);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return QString(QObject::tr("%1 KiB")).arg(bytes / 1024);
return QString(QObject::tr("%1 KB")).arg(bytes / 1000);

Shouldn't we instead refactor to abide by the IEC 80000-13 standard where 1 KB=1000 bytes (base 10)? macOS and Unix use this IEC standard, Windows is one of the only systems still treating 1KB=1024 bytes (base 2).

Or determine the system type and use its standard. So for Unix/macOS systems use base 10, for Windows use base 2.

Copy link
Author

@ghost ghost Mar 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be ok with that. Also with KB/s and change the divisor there accordingly form 1024 to 1000 (see e.g. Ubuntu units policy, which says for network bandwidth base-10 should be used). Whatever approach to solve, having unit KB with divisor 1024 is not correct I think. Edit: network bandwidth is something other than network throughput/transfer rate.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wodry yeah, I would say change this to base-10 instead and update the pr/commit description

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the title to be open for either approach. Would like to see more opinions.

Copy link
Member

@jarolrod jarolrod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this mebibyte/gibibyte naming scheme can be confusing to non-technical users

@ghost ghost changed the title gui: Display binary prefixes for power-of-2 byte values Fix incorrect prefix name for values of "Bytes transferred" and "Bytes/s" Mar 15, 2021
@hebasto
Copy link
Member

hebasto commented Mar 15, 2021

Concept ACK on being consistent.

My vote is for decimal prefixes for data transfer rates and amounts of the transferred data, that means usage of kB/s, kilobyte per second, and kB, kilobyte. Note, that the small letter "k" is a standard prefix that means "kilo".

https://en.wikipedia.org/wiki/Data-rate_units#Unit_prefixes:

The letter K is often used as a non-standard abbreviation for 1,024, especially in "KB" to mean KiB, the kilobyte in its binary sense.

@ghost
Copy link
Author

ghost commented Mar 16, 2021

My vote is for decimal prefixes

Thanks, so you would vote to change the divisor from 1024 to 1000 together with renaming KB to kB, right?

@hebasto
Copy link
Member

hebasto commented Mar 16, 2021

My vote is for decimal prefixes

Thanks, so you would vote to change the divisor from 1024 to 1000 together with renaming KB to kB, right?

Yes. That is my suggestion.

@sipa
Copy link
Contributor

sipa commented Mar 18, 2021

No strong opinion on 1000-based vs 1024-based, but please use unit names consistent with what is chosen.

@ghost
Copy link
Author

ghost commented Mar 18, 2021

I updated so the prefixes are unchanged (aside of of KB->kB as @hebasto suggested), and just the divisor is corrected from 1024 to 1000.

@ghost
Copy link
Author

ghost commented Mar 18, 2021

Not sure if this * 1.0f is really needed or if there is a nicer solution. Just took it over.

@ghost
Copy link
Author

ghost commented Mar 18, 2021

This is how it looks now with the updated PR applied. The 1000-based prefixes have the advantage to be consistent with the 10-based scaling of the network throughput graph horizontal marker lines (e.g. 100 kB/s, 1000 kB/s like in the screenshot).

bildschirmfoto
bildschirmfoto2

if(bytes < 1024 * 1024 * 1024)
return QObject::tr("%1 MB").arg(bytes / 1024 / 1024);
if(bytes < 1000 * 1000)
return QObject::tr("%1 kB").arg(bytes / 1000);
Copy link
Member

@jarolrod jarolrod Mar 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hebasto: This seems like a good place for some context to translators. For example, look at the French translation below.
Screen Shot 2021-03-18 at 7 49 37 PM
I don't know how the decimal unit kB is written in French (Edit: It's written as ko), but how do we let a translator know that they are supposed to translate as thedecimal unit and not the binary unit?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We could add more translation context later, when bitcoin/bitcoin#21465 approach is implemented.

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approach ACK 200b503

@wodry

Do you mind applying clang-format-diff.py to your commit?

Comment on lines 132 to 133
float inRate = (bytesIn - nLastBytesIn) * 1.0f / timer->interval();
float outRate = (bytesOut - nLastBytesOut) * 1.0f / timer->interval();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why * 1.0f is required?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am no C++ expert, just took it over from / 1024.0f * 1000 before. If the 1024.0f was also not needed (I imagined it might have had some reason of C++ type conversion), I will remove the * 1.0f

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If type conversion is supposed, it would better to apply explicit conversion.

@@ -128,8 +128,9 @@ void TrafficGraphWidget::updateRates()

quint64 bytesIn = clientModel->node().getTotalBytesRecv(),
bytesOut = clientModel->node().getTotalBytesSent();
float inRate = (bytesIn - nLastBytesIn) / 1024.0f * 1000 / timer->interval();
float outRate = (bytesOut - nLastBytesOut) / 1024.0f * 1000 / timer->interval();
// Rates are in bytes/millisecond which is equal to kilobytes/second
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding a comment, is it better just choose proper names for variables?
E.g., in_rate_kilobytes_per_sec ?

@ghost
Copy link
Author

ghost commented Mar 19, 2021

Approach ACK 200b503

@wodry

Do you mind applying clang-format-diff.py to your commit?

Thanks for the tipp, have done that, will update.

@hebasto
Copy link
Member

hebasto commented Mar 19, 2021

May I suggest a change:

--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -759,14 +759,14 @@ QString formatNiceTimeOffset(qint64 secs)
 
 QString formatBytes(uint64_t bytes)
 {
-    if (bytes < 1000)
+    if (bytes < 1'000)
         return QObject::tr("%1 B").arg(bytes);
-    if (bytes < 1000 * 1000)
-        return QObject::tr("%1 kB").arg(bytes / 1000);
-    if (bytes < 1000 * 1000 * 1000)
-        return QObject::tr("%1 MB").arg(bytes / 1000 / 1000);
+    if (bytes < 1'000'000)
+        return QObject::tr("%1 kB").arg(bytes / 1'000);
+    if (bytes < 1'000'000'000)
+        return QObject::tr("%1 MB").arg(bytes / 1'000'000);
 
-    return QObject::tr("%1 GB").arg(bytes / 1000 / 1000 / 1000);
+    return QObject::tr("%1 GB").arg(bytes / 1'000'000'000);
 }
 
 qreal calculateIdealFontSize(int width, const QString& text, QFont font, qreal minPointSize, qreal font_size) {
diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp
index 9e0b67917..7e12410c8 100644
--- a/src/qt/trafficgraphwidget.cpp
+++ b/src/qt/trafficgraphwidget.cpp
@@ -128,8 +128,8 @@ void TrafficGraphWidget::updateRates()
 
     quint64 bytesIn = clientModel->node().getTotalBytesRecv(),
             bytesOut = clientModel->node().getTotalBytesSent();
-    float in_rate_kilobytes_per_sec = (bytesIn - nLastBytesIn) / timer->interval();
-    float out_rate_kilobytes_per_sec = (bytesOut - nLastBytesOut) / timer->interval();
+    float in_rate_kilobytes_per_sec = static_cast<float>(bytesIn - nLastBytesIn) / timer->interval();
+    float out_rate_kilobytes_per_sec = static_cast<float>(bytesOut - nLastBytesOut) / timer->interval();
     vSamplesIn.push_front(in_rate_kilobytes_per_sec);
     vSamplesOut.push_front(out_rate_kilobytes_per_sec);
     nLastBytesIn = bytesIn;

?

It makes qt/guiutil.cpp more readable due to the nice C++17 feature :), and applies correct type conversion (without it the result will be integer by value).

@ghost
Copy link
Author

ghost commented Mar 19, 2021

Thanks very much for the high quality coding hints! Updated commit. (and did a successfull local build on Debian Buster (Qt 5.11.3) and test run, too)

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK d09ebc4, tested on Linux Mint 20.1 (Qt 5.12.8) the both "Network Traffic" and "Peers" tabs of the "Node Window".

@ghost ghost changed the title Fix incorrect prefix name for values of "Bytes transferred" and "Bytes/s" Fix: For values of "Bytes transferred" and "Bytes/s" with 1000-based prefix names use divisor 1000 instead of 1024 Mar 19, 2021
@ghost ghost changed the title Fix: For values of "Bytes transferred" and "Bytes/s" with 1000-based prefix names use divisor 1000 instead of 1024 Fix: For values of "Bytes transferred" and "Bytes/s" with 1000-based prefix names use 1000-based divisor instead of 1024-based Mar 19, 2021
Copy link
Member

@jarolrod jarolrod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK d09ebc4

Tested on macOS 11.1 Qt 5.15.2

@hebasto
Copy link
Member

hebasto commented Mar 22, 2021

@jonatack Do you mind looking into this PR?

Copy link

@leonardojobim leonardojobim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested ACK d09ebc4 on Ubuntu 20.04 Qt 5.12.8

@hebasto
Copy link
Member

hebasto commented Mar 23, 2021

Additional discussion from IRC:

<Arvidt> Any preference for having base-10 (kB/MB/GB) or base-2 (KiB/MiB/GiB) prefix for GUI network peer tab data transferred/throughput value? See #248 Would be thankful to get some feedback.
<luke-jr> Arvidt: base 10 sucks ;)
<hebasto> luke-jr: what reasons for?
<luke-jr> hebasto: 10 is a multiple of 5 and 2
<luke-jr> but more importantly, networks tend to use base-1024 measurements
<sipa> my gigabit ethernet does 1000000000 bits/s
<luke-jr> sipa: it does? :o
<sipa> yes
<luke-jr> hmm
<sipa> all network stuff is 1000-based, as far as i know'
<sipa> only disk sizes use 1024-based units conventionally
<sipa> or on-disk sizes
<luke-jr> RAM typically does even now
<sipa> that's true, RAM is also typically 1024-based

@jnewbery
Copy link
Contributor

Concept ACK. Using powers of 10 and correctly calling them kB and MB seems reasonable for a user-facing GUI.

@maflcko maflcko merged commit 837e59e into bitcoin-core:master Mar 23, 2021
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Mar 23, 2021
…d "Bytes/s" with 1000-based prefix names use 1000-based divisor instead of 1024-based

d09ebc4  Fix wrong(1024) divisor for 1000-based prefixes (wodry)

Pull request description:

  v.0.21.0

  I saw in the GUI peer window in the "received" column `1007 KB`, and after increasing to >=1024 I guess, it switched to `1 MB`. I would have expected the display unit to change from KB to MB already at value >=1000.

  I looked into the code, and the values appear to be power-of-2 byte values, so the switching at >=1024 and not >=1000 seems correct.
  But the unit display is not precisely correct, binary prefixes should be used for power-of-2 byte values.

  To be correct, this PR changes ~~KB/MB/GB to KiB/MiB/GiB.~~ KB to kB and the divisor from 1024 to 1000.

ACKs for top commit:
  hebasto:
    ACK d09ebc4, tested on Linux Mint 20.1 (Qt 5.12.8) the both "Network Traffic" and "Peers" tabs of the "Node Window".
  jarolrod:
    ACK d09ebc4
  leonardojobim:
    Tested ACK bitcoin-core/gui@d09ebc4 on Ubuntu 20.04 Qt 5.12.8

Tree-SHA512: 8f830b08cc3fd36dc8a18f1192959fe55d1644938044bf31d770f7c3bf8475fba6da5019a2d2024d5b2c81a8dab112f360c555367814a14f4d05c89d130f25b0
@ghost ghost deleted the binary-prefix branch March 28, 2021 20:39
gwillen pushed a commit to ElementsProject/elements that referenced this pull request Jun 1, 2022
@bitcoin-core bitcoin-core locked as resolved and limited conversation to collaborators Aug 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants